Автозавершение для Rake



    Автозавершение в bash’е по Tab’у — это невероятно удобная вещь. И оно точно нужно для rake, которым каждый программист на Ruby пользуется часто.

    Особо ленивые программисты уже давно прописали самодельные скрипты в своих .bashrc. Но настоящий дзен-программист не должен любить велосипеды и чтит репозитории и пакеты. Поэтому я собрал скрипт в пакет и выложил в Ubuntu on Rails PPA.

    Установка


    Ubuntu
    1. Добавляем Ubuntu on Rails PPA:
      $ sudo add-apt-repository ppa:ubuntu-on-rails/ppa
    2. Устанавливаем пакет rake-completion:
      $ sudo apt-get install rake-completion
    Другие UNIX
    1. Клонируем репозиторий:
      $ git clone git://github.com/ai/rake-completion.git
    2. Копируем скрипт в системную папку:
      $ sudo cp rake-completion/rake /etc/bash_completion.d/.

    Подробности


    Задачи Rake кешируются в .rake_tasks~ в папке проекта, поскольку, например, в Rails Rakefile запускается очень медленно, так как сначала загружает всё окружение проекта.

    Чтобы кеш и резервные копии не попали в git-репозиторий просто добавьте в .gitignore: *~

    Кеш автоматически обновляется, при изменениях в Rakefile или каких-нибудь *.rake файлов в проекте.

    Скрипт написан на sh. Должен работать и в zsh. В репозитории есть тесты тоже на sh :).
    Поделиться публикацией

    Комментарии 24

    • НЛО прилетело и опубликовало эту надпись здесь
        +1
        При попытке поставить пакет вылетает ошибка (Ubuntu 9.10):

        Unpacking rake-completion (from .../rake-completion_0.1~railsppa1_i386.deb)…
        dpkg: error processing /var/cache/apt/archives/rake-completion_0.1~railsppa1_i386.deb (--unpack):
        trying to overwrite '/etc/bash_completion.d/rake', which is also in package rake 0:0.8.4-1
        Errors were encountered while processing:
        /var/cache/apt/archives/rake-completion_0.1~railsppa1_i386.deb
        E: Sub-process /usr/bin/dpkg returned an error code (1)
        A package failed to install. Trying to recover:
        Reading package lists… Done
        Building dependency tree
        Reading state information… Done
        Reading extended state information
        Initializing package states… Done
          0
          Значит автозавершение вам не нужно и оно уже есть :). Я просто больше люблю rake из rubygems ставить, а там он без автозавершения.
            +1
            Как я посмотрел в пакет rake автозавершение без кеша. Я могу сделать возможность установки моего автозавершения к rake из пакета Ubuntu, если Вам это нужно. Правда пока не знаю, как сделать это наиболее красиво.
              0
              Выпустил версию 0.2, которая ставиться вместе с Rake из Ubuntu и заменяет его автозавершение.
              0
              Спасибо, поставил, отличная вещь!
              Родное автодополнение слишком долгое, а Ваше просто летает.
                0
                странно, при попытке дополнить
                rake db:mi<TAB>
                

                дополняет до
                rake db:middleware
                

                  0
                  Скрипт автодополняет только задачи с описаниями (который показываются по rake -T). Может проблема в этом?
                    0
                    $ rake -T | grep db:mi
                    rake db:migrate                           # Migrate the database through scripts in db/migrate and update db/schema.rb by invoking db:schema:dump. Target specific version with VERSION=x. Turn off output with VERBOSE=false.
                    rake db:migrate:down                      # Runs the "down" for a given migration VERSION.
                    rake db:migrate:redo                      # Rollbacks the database one migration and re migrate up.
                    rake db:migrate:reset                     # Resets your database using your migrations for the current environment
                    rake db:migrate:up                        # Runs the "up" for a given migration VERSION.
                    
                      0
                      На свежей установке рельсов всё работает. Наверное кеш рассинхронизовался. Rake RubyGems? Свой скрипт автодополнения не ставили? Какие были последние действия над репозиторием?
                        0
                        разобрался, спасибо. был другой скрипт автодополнения
                  0
                  Что люди только не делают лишь бы не использовать zsh :)
                    0
                    А он это все умеет проще? Где просвятиться?
                      –2
                      Он это умеет в поставке :) Как там сделано я не смотрел. Но помоему аналогичным способом.
                      0
                      zsh тут совершенно не при чём. Просто Rake из репозиториев Ubuntu уже имеет автозавершение для bash ;). Но он без кеширования, так что на сложным Rakefile (как у Rails) тормозит. Собственно, мой скрипт базируется на скрипте автозавершение для zsh, так что zsh не может иметь в поставке такой скрипт.
                        0
                        Да?
                        нюню
                        смотрим
                        -<%>- ls /opt/local/share/zsh/4.3.10/functions | grep rake
                        _rake
                        -<%>- cat /opt/local/share/zsh/4.3.10/functions/_rake
                        #compdef rake

                        # rake, version 0.8.3

                        local curcontext="$curcontext" state line expl ret=1
                        typeset -A opt_args

                        _arguments -C -s -S \
                        '(--classic-namespace -C)'{--classic-namespace,-C}'[put Task and FileTask in the top level namespace]' \
                        '(--dry-run -n)'{--dry-run,-n}'[do a dry run without executing actions]' \
                        '(- *)'{--describe,-D}'[describe the tasks (matching the specified pattern), then exit]:pattern::' \
                        '(--execute -e)'{--execute,-e}'[execute some Ruby code and exit]:Ruby code:' \
                        '(--execute-print -p)'{--execute-print,-p}'[execute some Ruby code, print the result, then exit]:Ruby code:' \
                        '(--execute-continue -E)'{--execute-continue,-E}'[execute some Ruby code, then continue with normal task processing]:Ruby code:' \
                        '(- *)'{--help,-h,-H}'[display help information]' \
                        \*{--libdir,-I}'[include specified directory in the search path for required modules]:library directory:_files -/' \
                        '(--rakelibdir --rakelib -R)'{--rakelibdir,--rakelib,-R}'[auto-import any .rake files in the specified directory. (default is 'rakelib')]:rake library directory:_files -/' \
                        '(--nosearch -N)'{--nosearch,-N}'[do not search parent directories for the Rakefile]' \
                        '(- *)'{--prereqs,-P}'[display the tasks and prerequisites, then exit]' \
                        '(--quiet -q --silent -s --verbose -v)'{--quiet,-q}'[do not log messages to standard output]' \
                        '(--rakefile -f)'{--rakefile,-f}'[use specified file as the rakefile]:rake file:_files' \
                        \*{--require,-r}'[require specified module before executing rakefile]:library:->library' \
                        '(- *)--rules[trace the rules resolution]' \
                        '(--quiet -q --silent -s --verbose -v)'{--silent,-s}"[like --quiet, but also suppresses the 'in directory' announcement]" \
                        '(--system,-g)'{--system,-g}'[using system wide (global) rakefiles (usually '~/.rake/*.rake')]' \
                        '(- *)'{--tasks,-T}'[display the tasks (matching the specified pattern) with descriptions, then exit]:pattern::' \
                        '(--trace -t)'{--trace,-t}'[turn on invoke/execute tracing, enable full backtrace]' \
                        '(--quiet -q --silent -s --verbose -v)'{--verbose,-v}'[log message to standard output (default)]' \
                        '(- *)'{--version,-V}'[display version information]' \
                        '*:target:->target' && ret=0

                        case "$state" in
                        library)
                        local -a dirs
                        dirs=( $(_call_program directories ruby -e 'puts\ \$:' 2>/dev/null) ${(s.:.)opt_args[-I]} )
                        _wanted libraries expl library _path_files -W dirs && ret=0
                        ;;
                        target)
                        local -a targets
                        targets=( ${${(f)"$(_call_program targets $words[1] -sT $opt_args[(I)(-N|--nosearch)] ${(kv)opt_args[(I)(-f|--rakefile)]} 2>/dev/null)"}/(#b)rake ([^ ]##) ##\# (*)/${${match[1]}//:/\\:}:${match[2]:l}} )
                        if ((! ${targets[(I)rake aborted!]} )) then
                        _describe -t targets 'rake target' targets && ret=0
                        else
                        _message -e targets 'rake target'
                        fi
                        ;;
                        esac

                        return ret
                          0
                          ОК, значит добавили, но я не заметил в коде (правда, он очень трудночитаем) кеширования задач. Как я понял они просто аргументы автозавершают.
                            0
                            так он кеширует все как бы :) это не bash :)
                              0
                              При всём моём уважении к zsh, это не Святой грааль :). Он не может автоматически кешировать, так как же он тогда обновляет кеш? Где-то должен быть код проверки времени модификации файлов Rakefile и **/*.rake. Это не может работать автоматически.
                                0
                                Да грааль не «святой», но очень удобный.
                                во время текущего запущенного zsh он кеширует команды которые вы используете.
                                  0
                                  Но тогда подправив Rakefile можно очень долго гадать куда делась новая задача. А заново открыв консоль с Rails-проектом случайно нажав Tab снова придётся ждать пока прогрузится стек рельсов? В общем, автозавершение задач в чистом zsh всё равно хуже. И мой скрипт должен работать и с zsh тоже. А вот о завершении аргументов надо подумать :).
                                    0
                                    Ну я думаю если вы добавили новую задачу, то вы знаете её по имени :) Да и у каждого кеширования есть определенный срок жизни :)

                                    В любом случае, я не говорю что bash хуже, просто он имеет меньше плюшет и тд и тп. Да их добавляют, но не так быстро как хотелось бы :)
                                      0
                                      А кто говорит про bash? :) Просто у моего скрипта синтаксис автозавершения bash для обратной совместимости ;).
                                        +1
                                        ладно все молчу молчу :) Просто я ничего не ставил и у меня всё это уже давно работает :)

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                    Самое читаемое