Настраиваем Vim для работы с Python кодом

    Сейчас достаточно много постов и видео на тему как сделать из Vim Python IDE. Написать эту статью я решил потому, что уже долгое время пользуюсь этим редактором и надеюсь что мой опыт по его настройке, о котором я напишу в этой статье не помешает. Я не собираюсь делать из Vim «комбайн», напичкав его огромным количеством плагинов, а постараюсь обойтись средствами самого редактора и несколькими расширениями, которые помогут Python разработчикам чувствовать себя более комфортно. Давайте приступим.

    LiveReload

    Большинство web — разработчиков в наше время с трудом представляют свою жизнь без этого замечательного расширения. Оно есть в таких редакторах как WebStorm, Sublime Text и существует как отдельное приложение для редакторов не поддерживающих LiveReload. К сожалению Vim относится к таким редакторам. Расширение есть, но оно давно уже устарело и не поддерживает последний протокол LiveReload 2.

    К счастью есть замечательная консольная утилита, которая называется python-livereload. Из огромных плюсов данной утилиты — не нужно устанавливать плагин для Google Chrome, Firefox и т.д., утилита бесплатная. Получить исходники можно тут github.com/lepture/python-livereload установить ее можно через pip или easy_install:

    pip install livereload
    


    Прежде чем начать редактирование нам необходимо создать Guardfile, который является обычным Python скриптом.

    #!/usr/bin/env python
    from livereload.task import Task
    
    
    Task.add('css/*.css')
    Task.add('*.html')
    


    После чего в текущей директории мы можем запустить сервер LiveReload командой:

    livereload -p 8000
    


    Python-livereload так же поддерживает less, coffee, uglifyjs и slimmer. Достаточно импортировать соответствующую функцию из модуля livereload.compiler, например:

    #!/usr/bin/env python
    from livereload.task import Task
    from livereload.compiler import lessc, coffee
    
    
    Task.add('css/*.css')
    Task.add('*.html')
    Task.add('css/style.less', lessc('style.less', 'style.css')
    Task.add('js/main.coffee', coffee('main.coffee', 'main.js')
    


    Базовые настройки редактора vim

    Теперь поговорим о базовых настройках, которые помогут нам в дальнейшем комфортно работать с кодом. Для начала давайте установим клавишу leader.

    set mapleader = ","

    Клавиша leader позволяет нам создавать собственные комбинации, при этом не портя стандартные, которые уже присутствуют в редакторе. В качестве клавиши leader я установил комбинацию "," вы можете установить любую другую.

    Из редактора я постарался убрать все лишнее (кроме вкладок в GUI). Для этого воспользуемся следующими настройками

    if has('gui_running') " Глобальные настройки на GUI Vim
        set guioptions-=m " убираем меню
        " set guioptions-=e " убираем вкладки GUI делаем их как в консоли
        set guioptions-=T " убираем тулбар
        set guioptions-=r " убираем полосы прокрутки справа
        set guioptions-=L " убираем полосы прокрутки слева
        set background=light " Цвет фона темный или светлый
        set guioptions-=R
        set guioptions-=l
    endif
    


    Обратите внимание на закоментированную строку set guioptions-=e. Если ее включить вкладки у вас будут выглядеть как в консольном виме:



    Отступы между черточками, разделяющие окно редактора можно убрать так

    set fillchars=stl:\ ,stlnc:\ ,vert:│
    




    Теперь настроим не отображаемые символы, к ним относятся пробельные символы, символы переноса строки и символы табуляции. Я использую следующие настройки

    if has('multi_byte')
        if version >= 700
            " set listchars=tab:»\ ,trail:·,eol:¶,extends:→,precedes:←,nbsp:×
            set listchars=tab:▸\ ,eol:¬ # TextMate
        else
            set listchars=tab:»\ ,trail:·,eol:¶,extends:>,precedes:<,nbsp:_
        endif
    endif
    nmap <leader>l :set list!<CR>
    


    Я привязал комбинацию leader + l для включения и выключения не отображаемых символов, так как они не всегда нужны, а иногда даже мешают редактированию.

    Совет: иногда при вставке текста в редактор не сохраняется форматирование и в редакторе появляется какая то белиберда. Что бы этого избежать добавьте в vimrc строку set paste или перед вставкой текста введите команду :set paste

    Vundle

    Vundle позволяет с легкостью устанавливать и обновлять расширения. Далее в статье для установки расширений мы будем использовать именно этот плагин. Установка на займет много времени, поэтому давайте сразу его установим:

    git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle
    


    Теперь необходимо добавить следующие строки в .vimrc:

    set nocompatible
    filetype off
    set rtp+=~/.vim/bundle/vundle/
    call vundle#rc()
    
    " тут будем добавлять наши расширения
    
    filetype plugin indent on
    
    " тут пойдут наши собственные настройки vim
    


    Для установки расширений воспользуйтесь следующим форматом

    Bundle 'tpope/vim-fugitive' " установка из Github
    Bundle 'FuzzyFinder' " установка из репозиториев vim-scripts
    Bundle 'git://git.wincent.com/command-t.git' " установка из Git
    


    Powerline

    Статусная строка в vim выглядит уныло и некрасиво. К счастью есть плагин, который делает ее более информативной и красивой. Пример того, как выглядит строка состояния у меня



    Установка: Bundle 'Lokaltog/vim-powerline'

    Что бы отображалась ветка текущего репозитория git, в директории которого вы находитесь добавьте и установите Bundle 'tpope/vim-fugitive'. Для корректной работы Powerline необходимо скачать исправленные шрифты отсюда, установить их и прописать в редакторе. Например:

    set guifont=Menlo\ Regular\ for\ Powerline:h12
    


    Command-T

    Command-T это отличное расширение позволяющее вам быстро открывать файлы по их названию, переключаться между буферами или тегами.

    Установка: Bundle 'wincent/Command-T'
    Далее необходимо перейти в директорию расширения command-t и запустить rake make:

    cd .vim/bundle/command-t
    rake make
    


    Клавиатурные комбинации можно настроить следующим образом:

    map <leader>f :CommandT<CR>
    map <leader>b :CommandTBuffer<CR>
    


    Теперь по leader + f открывается Command-T, leader + b открывает список открытых буферов.



    Pyhton mode

    Python mode позволяет сделать из редактора почти что полноценную IDE. Из того, что умеет python-mode:

    1. Подсветка ошибок через pyflakes, pep8, pylint, mccable, pep257

    2. Полная поддержка Rope (RopeCompletion, RopeGotoDefinition, RopeRename, RopeAutoImport, и т.д.)

    3. Поддержка virtualenv



    Пример настроек python-mode

    " Включаем библиотеку Rope
    let g:pymode_rope = 1
    
    " Включаем linting
    let g:pymode_lint = 1
    
    " Какие ошибки подсвечивать
    let g:pymode_lint_checker = "pyflakes,pep8"
    
    " Отключаем надоедливое окно, отображающее ошибки и предупреждения
    let g:pymode_lint_cwindow = 0
    
    " Включаем поддержку virtualenv
    let g:pymode_virtualenv = 1
    
    " Подсветка синтаксиса и ошибок
    let g:pymode_syntax = 1
    let g:pymode_syntax_all = 1
    let g:pymode_syntax_indent_errors = g:pymode_syntax_all
    let g:pymode_syntax_space_errors = g:pymode_syntax_all
    
    " Отключаем фолдинг
    let g:pymode_folding = 0
    
    " Загружаем плагин для вставки брейкпоинтов
    let g:pymode_breakpoint = 1
    
    " По leader + e будет устанавливаться брейкпоинт
    let g:pymode_breakpoint_key = '<leader>e'
    


    Клавиатурные комбинации:
    Комбинация Описание
    C-c-g Go to definition
    C-space Rope autocomplete
    C-c-d Rope show documentation
    C-c-f Rope find occurrences


    Для Rope autocomplete я настроил комбинацию leader+c. Включается она так

    imap <leader>c <C-R>=RopeCodeAssistInsertMode()<CR>
    


    Мой файл конфигурации Vim с подробными комментариями можете посмотреть тут github.com/aliev/vim

    Другие полезные расширения vim

    MatchTag
    Bundle 'gregsexton/MatchTag'
    Подстветка парных html, xml тегов

    EndWise
    Bundle 'tpope/vim-endwise'
    Отличное расширение для рубистов, которое позволяет автоматически закрывать блоки в Ruby

    Emmet
    Bundle 'mattn/emmet-vim'
    Я очень долго ждал это расширение. Поддержка emmet (переименованный Zen Coding)

    T-Comment
    Bundle 'tomtom/tcomment_vim'
    Комментирование блоков кода с автоматическим определением языка
    Поделиться публикацией

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

      +1
      Спасибо за статью.
      Я не так давно использую vim для написания питонового кода, и, наверное, многие вопросы до сих пор «детские».

      Но было бы интересно посмотреть на полный воркфлоу вашей работы с питоновым проектом.
      С чего начинаете, как отлаживаете, как гоняете тесты.
      Как работаете с буферами и табами.
      Как происходит навигация по коду.
      Сложно сформулировать все вопросы из-за недостатка опыта.

      P.S. У вас rope autocomplete не притормаживает?
        0
        Тесты через консоль, как и всегда. Отладка, если необходима, то через pdb (кстати, посмотрите еще PuDB). По поводу табов и буферов поищите в Интернете документации много на эту тему, переключаюсь между буферами через Command-T. Если нужна навигация по коду попробуйте расширение Taglist, для создание файлов и директорий, а так же просмотра текущего каталога использую NERDTree. По поводу притормаживания Rope autocomplete почитайте тут, но автокомплитом пользуюсь редко.
        0
        Я бы еще порекомендовал расцветку slate: colorscheme slate.
        Лично у меня от нее почти не устают глаза.
          +1
          solarized — отличная схема. Существует как vundle plugin: github.com/altercation/vim-colors-solarized

          В целом хорошая статья. Тоже использую vundle и схожие хоткеи с запятой в качестве leader (многие брал с vimcasts).
          Отрывок с gui_options вызвал некоторое недоумение. Для объяснения удобен, но можно ведь короче:
          gui_options
          if has('gui_running')
            set guioptions=e
            set background=light
          endif
          
          0
          Для powerline есть некоторое количество легких аналогов. Например, мне больше по душе lightline.vim
            0
            Продолжая тему замены statusline в vim'е — перешёл на vim-airline него после того как Lokaltog/vim-powerline стал deprecated.

            Плюс у автора vim-airline отличный vimrc из которого можно почерпнуть массу полезных настроек.
              0
              Спасибо. Не знал что powerline устарел
                0
                Автор просто полностью переписал его на питон и отказался от поддержки прежней версии. Актуальную можно взять от сюда — github.com/Lokaltog/powerline
              0
              Спасибо за статью, в целом интересно, но хотелось бы указать на несколько мелочей.

              не собираюсь делать из Vim «комбайн», напичкав его огромным количеством плагинов
              Кажется, у Вас это не слишком хорошо получилось, в первую очередь из-за Python-mode, который по сутя является объединением функциональности целой кучи плагинов.

              nmap <leader>l :set list!<CR>
              Тут и в принципе лучше писать:
              nnoremap <leader>l :set list!<cr>
              И менять на nmap только где это необходимо.

              добавьте в vimrc строку set paste
              Не делайте так! 'paste' делает нерабочими практически все маппинги в режиме вставки и не должен использоваться таким образом, лучше pastetoggle выставить.

              set nocompatible
              Несколько утомило уже это видеть в каждой статье про настройку Vim, в документации к 'compatible' ведь написано:
              When a vimrc or gvimrc file is found while Vim is starting up, this option is switched off
                0
                Спасибо за ваш комментарий. set nocompatible требует расширение vundle, в документации написано что необходимо установить данную опцию. По поводу python-mode согласен
                  0
                  Так Vim сам сбросит эту опцию, если файл конфигурации называется .vimrc а не .exrc. Т.е. явно сбрасывать её нет необходимости, так как к моменту исполнения той строчки опция уже сброшена.
                    +1
                    Ага. А если вам по каким‐либо причинам надо использовать vim -u /path/to/.vimrc (например, хотите запустить vim с вашим vimrc на чужой машине или избежать использования системного /etc/vim/vimrc//etc/vimrc (зависит от дистрибутива)), то никакое название файла вам не поможет: с -u Vim запускается в режиме совместимости, если нет -N (про который легко забыть). Так что лучше воспользоваться замечательным принципом Python «явное лучше скрытого» и не говорить о ненужности.
                      0
                      Да, посмотрел описание ключа -u и там это явно написано. Я думаю, что кто его часто используют должны это знать и учитывать, а не надеяться на то, что где-то будет уже всё предусмотрено. Не уверен, что в данном случае «явное лучше скрытого» надо применять к файлу конфигурации, а не к параметрам. Хотя согласен, что здесь это может быть проще и удобнее.
                        0
                        set nocompatible — это и есть учёт. «Не надеяться на то, что где‐то будет уже всё предусмотрено» для собственного файла настроек имеет не больше смысла, чем засовывать весь vimrc в аргументы командной строки. Чем строчка set nocompatible так принципиально отличается от inoremap ,a <C-o>A, что на присутствие второй я надеяться могу, а на присутствие первой — нет?
                          0
                          Да я в целом согласен, что корректнее настраивать файл настроек в нём же. Но меня никак не покидает чувство «костыльности» данного решения, так как на практике в 99% запусков, эта строчка не нужна, а вот сочетания нужны всегда. А пользователи читают везде, что нужна, и потом думают, что она прямо таки жизненно необходима. Не знаю, может меня теребит именно эта неосведомлённость.
                            0
                            Я считаю костыльной неочевидную логику, когда set nocompatible в начале vimrc эквивалентно наличию .vimrc с определённым именем файла в определённом месте, загружаемого определённым образом (точнее, одним из двух определённых способов: по‐умолчанию и с $VIMINIT; во втором случае имя не важно). Это слишком много условий, для того, чтобы на них можно было положиться. И слишком много возможных причин их нарушить (хотя, конечно, нарушение не происходит в большинстве случаев).

                            Если быть точным: я бы не стал внедрять такую логику вообще, если бы писал Vim.
                +2
                Вместо Command-T можно использовать CtrlP.
                Этот плагин удобнее, потому что он ищет не только в файлах, но и в буферах, поддерживает регулярные выражения и так далее.
                Очень функциональный плагин.
                  +1
                  И, что тоже плюс, не требует Ruby.
                    +1
                    Command-T тоже ищет в буферах. Точнее, он ищет либо там, либо там.

                    Command-T плох тем, что в issues уже весьма давно лежит патч, позволяющий расширять Command-T (т.е. использовать свою функцию создания списка), но никаких средств расширения нет до сих пор. В CtrlP они есть, причём с неплохим API. Когда мне надо было написать расширение для Command-T пришлось делать так: унаследоваться от главного класса, перед показом списка заменить глобальную переменную на экземпляр наследника, после показа вернуть всё как было. Вероятно, можно было изменить исходный экземпляр (хранится в $command_t), но я категорически не люблю monkey patching.

                    Command-T имеет часть, написаную на C, прослойку на VimL и большое количество кода на Ruby. CtrlP — полностью VimL, а потому работает медленнее.

                    Command-T не поддерживает не‐ASCII. Не знаю, как у CtrlP, но со стороны авторов Command-T можно было поддержать Unicode простым проходом по всему списку и созданием привязки для каждого нового найденного там символа.

                    Вообще, если бы мне не пришлось просмотреть исходный код обоих, я бы, наверное, использовал CtrlP. Но ужас с кучей глобальных переменных, сокращёнными до нельзя именами команд, принудительной установкой в modeline неудобных мне опций и, возможно, чем‐то ещё (смотрел давно) не выглядит как дополнение, которое может быть хорошим.

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

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