LINUX.ORG.RU

Веб-разработка в Vim

 


28

11

Предлагаю обсудить и поделиться опытом по веб-разработке в Vim.

Я использую Vim в терминале termite (со своими патчами для дефолтного копипаста и прочее) с цветовой схемой gruvbox: как для терминала, так и для Vim.

Этот клавиатура-ориентированный vim-like терминал я упомянул не столько потому, что у него реализованы режимы как Vim (insert mode, selection mode, выделение клавиатурой включая блочное), а потому, что у него есть приятная фича (которую можно наблюдать в iTerm2 для OS X) при работе Vim'а в нём, а именно цвет курсора изменяется в зависимости от цвета символа, на котором находится курсор, а также при выделении цвет выделения повторяет цвет слов/строк (но без инвертирования где нужно, может еще допилят), скриншот.

Менеджер плагинов:

Перед обсуждением плагинов и настроек, хочу подчеркнуть почему я использую менеджер плагинов vim-plug: перепробовав все известные менеджеры плагинов, включая недоменеджер pathogen, остановился именно на vim-plug потому, что он самый быстрый (параллельная установка/обновление, к-во потоков настраивается), имеет приятный интерфейс, краткий синтаксис, а самое главное позволяет настроить загрузку или отключение плагинов по filetype и/или первому вызову самого плагина, это не только ускоряет старт/работу Vim, но и помогает разрулить конфликты некоторых плагинов, простой пример:

Plug 'tpope/vim-endwise',   { 'for': [ 'ruby','vim','sh','zsh' ] }
Плагин endwise будет загружен только для ft=ruby,vim,sh,zsh, т.к. если этот полезный плагин работает одновременно с не менее полезным плагином delimitMate, то возникает конфликт в файлах с ft=css,js и везде, где после открытия скобки нужен автоматический переход на следующую строку и автозакрытие скобки.

Кроме всего прочего, отдельно от веб-разработки-related для самого вима у меня такое:

Автоматическое переключение на английский в Normal mode и обратно на предыдущий в Insert mode:

Конечно же нужно решать проблему с локалями (т.к. веб-разработка, в отличие от программирования иногда ведется на отличных от английского языках), а именно с неудобством при их переключении в Normal mode и обратно, самое лучшее решение, это установка в систему xkb-switch + плагин в Vim для него.

Plug 'lyokha/vim-xkbswitch'
let g:XkbSwitchEnabled       = 1
let g:XkbSwitchLib           = '/usr/lib64/libxkbswitch.so'
let g:XkbSwitchIMappings     = ['ru']
let g:XkbSwitchSkipIMappings = {'*' : ['[', ']', '{', '}', "'"]}
Теперь не нужно переключать на английский входя в Normal mode и на русский обратно в Insert mode, переключение происходит автоматически. Очень удобно.

Линейка номеров строк:

set nu
set nuw=4
autocmd InsertEnter * set nornu
autocmd InsertLeave * set rnu
в Insert mode - с номерами строк всё как обычно, в Normal mode (точнее после первого входа в insert и выхода обратно в normal) включается типа линейки: скриншот.

Автоматическая паста с отступами:

Чтобы навсегда забыть эту проблему и не включать перед пастой каждый раз режим пасты или использовать хитрые хоткеи, можно просто добавить настройку:

let &t_SI .= "\<Esc>[?2004h"
let &t_EI .= "\<Esc>[?2004l"
inoremap <special> <expr> <Esc>[200~ XTermPasteBegin()
function! XTermPasteBegin()
  set pastetoggle=<Esc>[201~
  set paste
  return ""
endfunction

Замена заменяемого без удаления (проблема забивания иксового буфера обмена):

Чтобы заменить слово или кусок окруженный делиметрами без удаления в иксовый буфер, можно использовать такую настройку на хоткей S :

nnoremap <silent> S :set opfunc=PasteReplace<CR>g@
function! PasteReplace(type, ...)
    if a:0
        silent exe "normal! `<" . a:type . "`>p"
    elseif a:type == 'line'
        silent exe "normal! '[V']p"
    elseif a:type == 'block'
        silent exe "normal! `[\<C-V>`]p"
    else
        silent exe "normal! `[v`]p"
    endif
endfunction
nmap SS S$
Теперь если нужно заменить слово без его удаления, можно просто: Sw , Si" , Si( , и т.п.

Проекты/сессии:

Плагин vim-startify - стартовый экран, можно настроить на сессии и букмарки, чтобы каждый раз не открывать то же самое в сплиты/табы/буферы.

Документация:

Для открытия документации в браузере (как минимум для того, что нас интересует: HTML, JavaScript, CSS, SCSS, LESS, Ruby, Rails, Django, PHP и т.п.) исходя из из ft= и положения курсора, удобно замапить на F1:

Plug 'Keithbsmiley/investigate.vim'
nnoremap <F1> :call investigate#Investigate()<CR>

Автокомплит и сниппеты:

В отличие от YouCompleteMe, автокомплитер neocomplete не тормозит (при работе и старте), не нужен питон (но нужен lua), а всё остальное такое же (для веб-разработки). Интегрируется с родным движком сниппетов neosnippet, который работает как с родными, так и универсальными vim-snippets (объединенные Snipmate & UltiSnip).

Настройка для навигации по комплиту через Tab (сам комплит всплывает автоматически, можно настроить обратное):

imap <expr><TAB> neosnippet#expandable_or_jumpable() ? "\<Plug>(neosnippet_expand_or_jump)" : pumvisible() ? "\<C-n>" : "\<TAB>"
smap <expr><TAB> neosnippet#expandable_or_jumpable() ? "\<Plug>(neosnippet_expand_or_jump)" : "\<TAB>"
if has('conceal')
  set conceallevel=2 concealcursor=i
endif

ZenCoding/Emmet:

Полнофункциональный Emmet для Vim: emmet-vim

Работает как нужно, но по дефолту неудобный (как по мне) хоткей <c-y>, , я настроил себе на jk . Т.е. Esc у меня kj , а дополнить jk . Первое время пользовался F4, привожу настройки, но jk намного удобнее. Просто на Tab настроить нельзя (иначе как пользоваться Tab?).

Plug 'mattn/emmet-vim',           { 'for': ['html','xhtml','css','sass','scss','less'] }
au FileType html,css,sass,scss,less imap <expr><F4> emmet#expandAbbrIntelligent("\<tab>")
au FileType html,css,sass,scss,less imap <expr>jk   emmet#expandAbbrIntelligent("\<tab>")
au FileType html                    imap <C-\>      <CR><CR><Esc>ki<Tab>
Плагин MatchTag - для отображения парных тегов.

Кроме Emmet'а для Vim существует аналог: Sparkup (нужен питон, не пробовал).

Отображение отступов:

Можно настроить каким символом и цветом отображать линии отступов, я настроил на хоткей <A-i> , альт как непечатаемый символ, так что проще посмотреть настройку склонировав репу на гитхабе и заглянув в .vimrc (или нажать C-v A-хоткей), скриншот.

Plug 'Yggdroot/indentLine'
let g:indentLine_enabled    = 0
let g:indentLine_char       = '¦'
let g:indentLine_color_term = 239
let g:indentLine_color_gui  = '#A4E57E'
nmap ^[i :IndentLinesToggle<CR>

Подсветка синтаксиса:

Plug 'tpope/vim-haml',            { 'for': 'haml'   }
Plug 'wavded/vim-stylus',         { 'for': 'stylus' }
Plug 'groenewege/vim-less',       { 'for': 'less'   }
Plug 'digitaltoad/vim-jade',      { 'for': 'jade'   }
Plug 'slim-template/vim-slim',    { 'for': 'slim'   }
Plug 'othree/html5-syntax.vim',   { 'for': 'html'   }
Plug 'cakebaker/scss-syntax.vim', { 'for': 'scss'   }

Plug 'hail2u/vim-css3-syntax',    { 'for': ['html','css'] }
augroup VimCSS3Syntax
  autocmd!
  autocmd FileType css setlocal iskeyword+=-
augroup END

Проверка синтаксиса:

Для проверки синтаксиса используется Syntastic + сторонние чеккеры:

Plug 'scrooloose/syntastic', { 'for': ['ruby','html','css', 'javascript', 'haml'] }
let g:syntastic_auto_jump           = 1
let g:syntastic_error_symbol        = '✖'
let g:syntastic_warning_symbol      = '►'
let g:syntastic_javascript_checkers = ['jshint'   ] " sudo npm install -g jshint
let g:syntastic_html_checkers       = ['jshint'   ] " sudo npm install -g jshint
let g:syntastic_ruby_checkers       = ['rubylint' ] " gem install ruby-lint
let g:syntastic_haml_checkers       = ['haml-lint'] " gem install haml-lint
let g:syntastic_css_checkers        = ['csslint'  ] " sudo npm install -g csslint
let g:syntastic_css_csslint_args    = "--ignore=zero-units"

Деобфускация / beautify'еры:

Плагин vim-autoformat работает со сторонними 'formatprograms', например js-beautify для HTML, CSS и JavaScript. autopep8 для питона и т.д. Всё это должно быть установленно.

Plug 'Chiel92/vim-autoformat'
let g:formatprg_args_javascript = "-j -q -B -f -"
noremap  <F8>   :Autoformat<CR><CR>
vnoremap <C-F8> gq

JavaScript:

Дефолтная поддержка JavaScript в Vim на довольно низком уровне, так что необходимы плагины как для самого JS, так и для библиотек, плагин javascript-libraries-syntax поддерживает почти все основные либы: jQuery, underscore.js, Backbone.js, AngularJS, RequireJS, Sugar.js, Jasmine и т.д.

Plug 'moll/vim-node'
Plug 'pangloss/vim-javascript',      { 'for': 'javascript' }
Plug 'jelera/vim-javascript-syntax', { 'for': 'javascript' }
let javascript_enable_domhtmlcss = 1
let g:html_indent_inctags        = "html,body,head,tbody"
let g:html_indent_script1        = "inc"
let g:html_indent_style1         = "inc"

Plug 'othree/javascript-libraries-syntax.vim', { 'for': 'javascript' }
let b:current_syntax       = 'javascript'
let g:used_javascript_libs = 'angularjs'

Также полезен tern_for_vim (сам Tern должен быть установлен), который умеет в 'Jump to the definition', 'Find the type' и т.д.

Пробельные символы:

По A-w показывает, по \-dw удаляет. Перевести все табы в пробелы (вдруг кто не знает), в Vim: :retab .

Plug 'ntpeters/vim-better-whitespace'
let g:better_whitespace_enabled = 0
nmap ^[w :ToggleWhitespace<CR>
nmap <Leader>dw :StripWhitespace<CR>

И кое-какие настройки по-мелочи:

set splitbelow
set splitright
inoremap  kj           <Esc>
map       gm           :call cursor(0, virtcol('$')/2)<CR>
nnoremap  <F12>f       :exe ':silent !firefox %'<CR><C-l>
nnoremap  <F12>c       :exe ':silent !chromium-browser %'<CR><C-l>
1-2 строки: для нормального открытия (слева направо) сплитов.
3: Esc на kj - мегаудобно.
4: для попадания на средину строки.
И последние две для предпросмотра в браузерах.

Мой ~/.vimrc

Кто что использует и как, кроме вышеуказанного?

Ответ на: комментарий от coderage

Но если речь о веб, то тебе нужно переключаться на браузер и проверять результат.

Для этого есть E2E тесты.

anonymous
()
Ответ на: комментарий от x3al

А чем консольный vim лучше gvim в таких юзкейсах? Заодно исключаются все грабли с копипастой, скоростью отрисовки etc.

И vim, и gvim умеют иксовый буфер. Просто собирайте vim с его поддержкой.

А скорость отрисовки больше зависит от эмулятора терминала.

andreyu ★★★★★
()
Ответ на: комментарий от x3al

олее альтернативные редакторы вполне умеют мышь. Правда, кодить мышью в них не получится.

ЧТД.

andreyu ★★★★★
()

Очень интересно, спасибо Если кто кодит ещё и на perl (например с фреймворком Mojolicious), то советую посмотреть ещё этот семинар: http://www.youtube.com/watch?v=zItaMaJjygI .

erebtonge
()
Ответ на: комментарий от q11q11

мне и так 8 гиг рамы мало, а тут ещё и ЭТО минимум 2 прсит


https://dl.dropboxusercontent.com/u/20454826/screens/pycharm_memory.png
Ну и где IDEA жрёт 2 Гига? Ты хоть разберись как ей пользоваться, а потом визжи о потреблении. Уже много раз слышу на лоре наезды на потребление, тормоза и прочее, при этом никаких прувов нет. Ты хоть что делаешь на Vim? Что у тебя за деятельность такая, что тебе мало 8 гигов? У тебя открыто 30 программ? Почему я с 4 гигами не испытываю никих неудобств, о которых так кричат на лоре? И типа минимализм vim кому-то нужен в 2014 году, к тому же на нём ещё и кодить - это вообще бредятина. Всё-равно что, кодить под nano или в блокноте :)

menangen ★★★★★
()
Ответ на: комментарий от menangen

ну и каким боком твой скрин относится к линуксу?

Firefox, 45.7 Mb, 41 поток

шёл бы ты обрано в свою вселенную, откуда случайно вывалился да ещё и сайтом ошибся

И типа минимализм vim кому-то нужен в 2014 году

вот ты бы как раз разобрался на тему минимализма VIM
и визжишь тут только ты
почему?
да потому что влез со своим уставом в чужой монастырь и чего-то пытаешь доказать

Ты хоть что делаешь на Vim?

ты вопрос можешь нормально сформулировать?

к тому же на нём ещё и кодить
Что у тебя за деятельность такая, что тебе мало 8 гигов?
Почему я с 4 гигами не испытываю никих неудобств, о которых так кричат на лоре?

именно потому что ты КОДИШЬ helloworld-ы
я же в отличии от тебя занимаюсь веб-разработкой, и VIM лишь один из многих удобных мне инструментов

q11q11 ★★★★★
()
Ответ на: комментарий от q11q11

Так напиши человеку, что ты можешь сделать в виме, чего он не сможет сделать в идее, че агришься-то сразу?

anonymous
()
11 сентября 2014 г.
Ответ на: комментарий от VimCasts

Каждый раз добавлять дополнительный тег script на страницу? А при разворачивании в продакшен - удалять? Как это может быть удобно?

только Firefox?

А разве есть другие браузеры?

anonymous
()
Ответ на: комментарий от anonymous

Каждый раз добавлять дополнительный тег script на страницу?

ты что-ли каждую страницу с 0 пишешь или таки используешь boilerplate'ы, где скрипт уже есть?

А при разворачивании в продакшен - удалять?

это занимает для малой персональной электронной вычислительной машины не более миллисекунды.

только Firefox?
А разве есть другие браузеры?

кормят в другом разделе форума, не здесь.

VimCasts
() автор топика

Плагин MatchTag - для отображения парных тегов.

Совершенно случайно наткнулся на более лучший, в некотором смысле, плагин для этого: MatchTagAlways.

Разница в между ними в том, что в случае MatchTagAlways, как это видно из названия, отображение парных тегов происходит постоянно во время пребывания в нём, а не только на нём, как это делает MatchTag.

По ссылке понятная картинка.

vim
()
25 ноября 2014 г.

А чем форматировать html? vim-autoformat умеет несколько внешних утилит для форматирования, но ни одна не работает.

cast vim.

anonymous
()
Ответ на: комментарий от anonymous

чем форматировать html?

html-beautify, который в комплекте с js-beautify:

sudo npm install -g js-beautify
в виме использовать vim-autoformat, дополнительная настройка не нужна, это дефолтный форматер для js, html и css.

vim
()
Ответ на: комментарий от anonymous

vim-autoformat умеет несколько внешних утилит для форматирования, но ни одна не работает.

у меня прекрасно отформатировал обфусцированный html лор-трекера, что-то не то у тебя.

до:

<!DOCTYPE html><html lang=ru><head><link href='https://fonts.googleapis.com/css?family=Droid+Sans+Mono|Open+Sans:600&amp;subset=latin,cyrillic' rel='stylesheet' type='text/css'><link rel="stylesheet" type="text/css" href="/tango/combined.css?20141223-0938"><title>Последние сообщения</title><link rel="search" title="Search L.O.R." href="/search.jsp"><meta name="referrer" content="always"><base href="https://www.linux.org.ru/"><link rel="shortcut icon" href="/favicon.ico" type="image/x-icon"><link rel="yandex-tableau-widget" href="/tango/manifest.json" /><meta name="viewport" content="initial-scale=1.0"></head><body><div id="hd"><a id="sitetitle" href="/">LINUX.ORG.RU</a><div class="menu"><div id="loginGreating"><a style="text-decoration: none" href="/people/vim/profile">vim</a></div><ul><li><a href="/news/">Новости</a></li><li><a href="/gallery/">Галерея</a></li><li><a href="/forum/">Форум</a></li><li><a href="/tracker/">Трекер</a></li><li><a href="/wiki/">Wiki</a></li><li><a href="notifications">Уведомления <span id="main_events_count"></span></a></li><li><a href="/search.jsp">Поиск</a></li></ul></div></div></body></html>
после:
<!DOCTYPE html>
<html lang=ru>

<head>
  <link href='https://fonts.googleapis.com/css?family=Droid+Sans+Mono|Open+Sans:600&subset=latin,cyrillic' rel='stylesheet' type='text/css'>
  <link rel="stylesheet" type="text/css" href="/tango/combined.css?20141223-0938">
  <title>Последние сообщения</title>
  <link rel="search" title="Search L.O.R." href="/search.jsp">
  <meta name="referrer" content="always">
  <base href="https://www.linux.org.ru/">
  <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
  <link rel="yandex-tableau-widget" href="/tango/manifest.json" />
  <meta name="viewport" content="initial-scale=1.0"> </head>

<body>
  <div id="hd"> <a id="sitetitle" href="/">LINUX.ORG.RU</a>
    <div class="menu">
      <div id="loginGreating"> <a style="text-decoration: none" href="/people/vim/profile">vim</a> </div>
      <ul>
        <li><a href="/news/">Новости</a>
        </li>
        <li><a href="/gallery/">Галерея</a>
        </li>
        <li><a href="/forum/">Форум</a>
        </li>
        <li><a href="/tracker/">Трекер</a>
        </li>
        <li><a href="/wiki/">Wiki</a>
        </li>
        <li> <a href="notifications">Уведомления <span id="main_events_count"></span></a> </li>
        <li><a href="/search.jsp">Поиск</a>
        </li>
      </ul>
    </div>
  </div>
</body>

</html>

vim
()
Последнее исправление: vim (всего исправлений: 2)
Ответ на: комментарий от anonymous

Странно, почему у меня раньше не срабатывало.

anonymous
()
Ответ на: комментарий от anonymous

на самом деле перенес, это так сюда вставилось, можешь попробовать у себя.

vim
()
Ответ на: комментарий от anonymous

и au BufWritePre *.html :Autoformat.

зачем форматить каждый открытый html?

я себе сделал так:

noremap  <F8>   :Autoformat<CR><CR>
vnoremap <C-F8> gq

vim
()
Ответ на: комментарий от vim

Почему каждый открытый? Только те, которые изменяешь и сохраняешь. А помнить все эти кейбиндинги - ну его нафиг.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.