Эта публикация рассказывает о том, как экономить время при разработке для Clojure и NodeJS, а также Bash скриптов, посылая текст из vim в REPL, c использованием tmux + vim + vim-slime. Также приводятся рецепты с nodemon.
Скорее всего, vim-slime сработает и для других интерпретируемых языков (Ruby / Python / PHP / Perl ...). vim-slime также работает со screen.
На хабре достаточно освещались и vim, и tmux. Я только хотел показать, что можно получить от их комбинации.
Добавление от Fikys: с Ruby работает.
Если вы знаете vim и tmux, и вам интересен только vim-slime — прыгайте сразу ко второй секции.
Мы все стремимся быть производительными. После того, как код написан, мы хотим узнать, работает ли он и получить обратную связь. Мы придумали много способов ускорения обратной связи: статическое выведение типов при компиляции и в IDE, юнит-тесты, интеграционные тесты, REPL, LiveReload и т.д.
Для моих небольших проектов я использую связку REPL и юнит-тестов, что позволяет получать обратную связь мгновенно.
Я веб-разработчик. По работе и в своем проекте обычно я делаю фронтэнд и стыкующуюся с ним часть бэкэнда. В течении рабочей сессии я пишу PHP, phtml, Stylus, css, Coffeescript, Javascript, + sql запросики и пуши в гит; что обеспечивается связкой tmux и vim. Также есть пара маленьких проектов на CoffeeScript, для которых используется комбо tmux + vim + vim-slime + Coffeescript REPL. В проектной сессии увязываются Сlojure, CoffeeScript, Stylus; tmux + vim + vim-slime + Clojure REPL. Под катом я расскажу об трех сетапах для трех окружений.
На работе я пишу phtml шаблоны, подключаю в них данных из контроллеров Зенда, вешаю на шаблоны скрипты и стили. Чтобы не путаться в нескольких разных контекстах я разнес все по нескольким окнам tmux. По одному окну и запущенному виму для php / phtml, stylus, coffee, js. Еще четыре вспомогательных окошка для ssh, mysql, git и смотрящих компиляторов (coffee, stylus).
![tmux-work-guards](https://habrastorage.org/r/w1560/files/343/077/2c7/3430772c75fd44d3bec6ce481c941f58.png)
Раньше я держал все вкладки в одном экземпляре вима. tmux позволил запускать несколько экземляров vim и не путаться в них.
Я пишу свой набор функций для JS. Это AMD модуль, который превращается в CommonJS, с помощью «30 строк кода». Свеженаписанный CoffeeScript элементарно тестится с вим-слайм и потом идет под юнит-тесты.
Проект vim-slime, как его описывает его автор Джонатан Паларди (jpalardy@github) — это соединение хорошего редактора (vim) с всей крутотой REPL. Я очень отдаленно представляю, как работает настоящая SLIME, поэтому не могу дать справки по оригиналу. Кроме того, для vim есть более близкое к SLIME решение, но не такое простое в установке. Все, для чего мне нужен vim-slime — посылать текст из vim в REPL. Открываешь tmux, делишь экран на две вкладки — на левую ставишь vim, на правую твою любимую REPL. Пишешь код, жмешь <C-c><C-c> — текущий абзац перетекает в REPL и исполняется. Красота.
![vim-slime-coffee](https://habrastorage.org/r/w1560/files/cce/893/cb6/cce893cb6c6c4023981f675bb2e80dcc.png)
Обладателям Vundle достаточно поставить добавить в vimrc, и выполнить PluginInstall:
Обладетели Pathogen, соответственно, клонируют себе репозиторий с гитхаба.
По умолчанию плагин настроен на работу со screen. Чтобы он работал с tmux, в vimrc надо добавить вторую строчку:
При подготовке публикации выяснилось, что плагин не работает с CoffeeScript из коробки (c JS все норм). В моем случае это решилось включением второго плагина:
В работе это выглядит так. Запускаем tmux, делим экран надвое, открываем в vim любимый файл. На второй панели запускем REPL, например, Coffee или NodeJS.
Вот вам готовые кусочки кода на случай, если «лень»:
Выделяем интересующий нас кусочек кода через vim visual mode и <C-c><C-c>. Если ничего не выделять, то <C-c><C-c> отправит в REPL абзац (блок текста без пустых строк) под курсором.
При первом запуске команды за сессию vim-slime спрашивает имя tmux сокета и в какую `сессию-tmux: окно, панель` посылать текст. На первый вопрос отвечаем `default`, на второй `:0,1`. Enter! И код появляется в REPL.
Диалог настройки можно вызвать самостоятельно через `:SlimeConfig`. Можно также посылать код в другое окно терминала, что может быть удобно для людей, работающих с несколькими мониторами. Запустите второе окно с tmux, откройте свою REPL и в первом окне с vim выполните:
Где на третьей строке указано `название-сессии-tmux: окно, вкладка`.
![vim-slime-two-windows](https://habrastorage.org/r/w1560/files/d04/fe8/3ba/d04fe83ba9124649a13ae2069e558113.png)
Вы можете воспользоваться советом от dkiyatkin
В официальной документации есть совет как переназначить комбинацию в стиле вима:
Наиболее сложные и корневые (используемые другими функциями) функции библиотеки я покрыл простейшими (но достаточными) assert тестами.
Чтобы видеть результаты тестирования в течении секунд и не отвлекаться на рутину, есть nodemon. Это npm-пакет, который скармливает ноде js/coffee скрипт на старте и каждый раз при изменении отслеживаемых файлов. В итоге я узнаю о результатах тестирования каждый раз при сохранении файла.
![tmux-vim-nodemon](https://habrastorage.org/r/w1560/files/3f8/ff3/cf6/3f8ff3cf61ad459691c7811f6c990e37.png)
Для получения такой живой второй вкладки на ней запускается что-то вроде:
Эта публикация не появилась бы, если бы не наткнулся какого-то парня, описавшего свой сетап.
Также для Clojure есть vim-fireplace, который среди прочего умеет доставать документацию.
Я предпочел vim-slime по одной простой причине — REPL.
Кложуровский REPL-сервер (nrepl) и клиент (REPL-y, идет в комплекте с Leiningen) сами по себе умеют уйму полезных вещей. Поведение vim-slime максимально примитивно и предсказуемо. Более того, когда REPL-y бежит в соседней вкладке, вы видите все историю и трейсы ошибок, а помимо самих возможностей REPL-y доступен еще и функционал tmux по работе с текстом. Вы можете переключится в REPL и исполнить там то, что не хотите писать и стирать в виме, и переключиться обратно.
![tmux-vim-clojure](https://habrastorage.org/r/w1560/files/66c/dd7/e22/66cdd7e2270b4bc78626c62aaaa8856f.png)
В целом опыт с Clojure REPL тот же, что и с NodeJS. Основное отличие от NodeJS REPL в том, что у Clojure REPL есть понятие пространства имен. Поэтому каждый раз, когда вы хотите послать в REPL конкретный кусочек кода, то приходится умудряться еще и переключить пространство имен. Это можно автоматизировать добавив в .vimrc:
Таким образом, при каждом переключении вкладок в REPL выставляется текущее пространство имен. Должно быть указано первой строкой в файле. Скорее всего это можно автоматизировать более элегантно.
Меня до сих пор приводит в детский восторг возможность открыть на соседней панели ssh-соединение с Штутгартом (hetzner) и передавать туда текст из Москвы. Таким образом, можно одновременно писать код и отлаживать удаленно. Также эта штука работает и с bash. На скриншоте в левой руке локальный vim, в правой руке удаленный bash:
![tmux-vim-bash](https://habrastorage.org/r/w1560/files/d84/b3d/201/d84b3d201a71445abfa5844db97fdf5c.png)
Чтобы упростить создание tmux-сессий, я использую руби-проект тмуксинатор.
1. .vimrc
2. .tmux.conf
Нельзя не упомянуть хабровчанина-минималиста d3m1gd, сделавшего свой vim-slime. Также хочется сказать спасибо всем просветителям, рассказывающим о vim, tmux, и других *-NIX инструментах.
Скорее всего, vim-slime сработает и для других интерпретируемых языков (Ruby / Python / PHP / Perl ...). vim-slime также работает со screen.
На хабре достаточно освещались и vim, и tmux. Я только хотел показать, что можно получить от их комбинации.
Добавление от Fikys: с Ruby работает.
Если вы знаете vim и tmux, и вам интересен только vim-slime — прыгайте сразу ко второй секции.
Вступление
Мы все стремимся быть производительными. После того, как код написан, мы хотим узнать, работает ли он и получить обратную связь. Мы придумали много способов ускорения обратной связи: статическое выведение типов при компиляции и в IDE, юнит-тесты, интеграционные тесты, REPL, LiveReload и т.д.
Для моих небольших проектов я использую связку REPL и юнит-тестов, что позволяет получать обратную связь мгновенно.
Я веб-разработчик. По работе и в своем проекте обычно я делаю фронтэнд и стыкующуюся с ним часть бэкэнда. В течении рабочей сессии я пишу PHP, phtml, Stylus, css, Coffeescript, Javascript, + sql запросики и пуши в гит; что обеспечивается связкой tmux и vim. Также есть пара маленьких проектов на CoffeeScript, для которых используется комбо tmux + vim + vim-slime + Coffeescript REPL. В проектной сессии увязываются Сlojure, CoffeeScript, Stylus; tmux + vim + vim-slime + Clojure REPL. Под катом я расскажу об трех сетапах для трех окружений.
Сетап 1 — «Рабочий»
На работе я пишу phtml шаблоны, подключаю в них данных из контроллеров Зенда, вешаю на шаблоны скрипты и стили. Чтобы не путаться в нескольких разных контекстах я разнес все по нескольким окнам tmux. По одному окну и запущенному виму для php / phtml, stylus, coffee, js. Еще четыре вспомогательных окошка для ssh, mysql, git и смотрящих компиляторов (coffee, stylus).
![tmux-work-guards](https://habrastorage.org/files/343/077/2c7/3430772c75fd44d3bec6ce481c941f58.png)
Раньше я держал все вкладки в одном экземпляре вима. tmux позволил запускать несколько экземляров vim и не путаться в них.
Сетап 2 — «Coffeescript»
Я пишу свой набор функций для JS. Это AMD модуль, который превращается в CommonJS, с помощью «30 строк кода». Свеженаписанный CoffeeScript элементарно тестится с вим-слайм и потом идет под юнит-тесты.
vim-slime
Проект vim-slime, как его описывает его автор Джонатан Паларди (jpalardy@github) — это соединение хорошего редактора (vim) с всей крутотой REPL. Я очень отдаленно представляю, как работает настоящая SLIME, поэтому не могу дать справки по оригиналу. Кроме того, для vim есть более близкое к SLIME решение, но не такое простое в установке. Все, для чего мне нужен vim-slime — посылать текст из vim в REPL. Открываешь tmux, делишь экран на две вкладки — на левую ставишь vim, на правую твою любимую REPL. Пишешь код, жмешь <C-c><C-c> — текущий абзац перетекает в REPL и исполняется. Красота.
![vim-slime-coffee](https://habrastorage.org/files/cce/893/cb6/cce893cb6c6c4023981f675bb2e80dcc.png)
Установка и настройка vim-slime
Обладателям Vundle достаточно поставить добавить в vimrc, и выполнить PluginInstall:
Plugin 'jpalardy/vim-slime'
Обладетели Pathogen, соответственно, клонируют себе репозиторий с гитхаба.
По умолчанию плагин настроен на работу со screen. Чтобы он работал с tmux, в vimrc надо добавить вторую строчку:
let g:slime_target = "tmux"
При подготовке публикации выяснилось, что плагин не работает с CoffeeScript из коробки (c JS все норм). В моем случае это решилось включением второго плагина:
Plugin 'kchmck/vim-coffee-script'
Пристрелка vim-slime
В работе это выглядит так. Запускаем tmux, делим экран надвое, открываем в vim любимый файл. На второй панели запускем REPL, например, Coffee или NodeJS.
Вот вам готовые кусочки кода на случай, если «лень»:
// js
function greeter(name) {
console.log("Hey, " + name + "!")
}
greeter("Jude")
# coffee
greeter = (name) ->
console.log "Hey, #{name}!"
greeter("Jude")
Выделяем интересующий нас кусочек кода через vim visual mode и <C-c><C-c>. Если ничего не выделять, то <C-c><C-c> отправит в REPL абзац (блок текста без пустых строк) под курсором.
При первом запуске команды за сессию vim-slime спрашивает имя tmux сокета и в какую `сессию-tmux: окно, панель` посылать текст. На первый вопрос отвечаем `default`, на второй `:0,1`. Enter! И код появляется в REPL.
Диалог настройки можно вызвать самостоятельно через `:SlimeConfig`. Можно также посылать код в другое окно терминала, что может быть удобно для людей, работающих с несколькими мониторами. Запустите второе окно с tmux, откройте свою REPL и в первом окне с vim выполните:
:SlimeConfig
default
2:0,0
Где на третьей строке указано `название-сессии-tmux: окно, вкладка`.
![vim-slime-two-windows](https://habrastorage.org/files/d04/fe8/3ba/d04fe83ba9124649a13ae2069e558113.png)
добавлено: Если <C-c><C-c> вам кажется неудобным
Вы можете воспользоваться советом от dkiyatkin
В официальной документации есть совет как переназначить комбинацию в стиле вима:
let g:slime_no_mappings = 1
xmap <leader>s <Plug>SlimeRegionSend
nmap <leader>s <Plug>SlimeMotionSend
nmap <leader>ss <Plug>SlimeLineSend
Модульное тестирование
Наиболее сложные и корневые (используемые другими функциями) функции библиотеки я покрыл простейшими (но достаточными) assert тестами.
Чтобы видеть результаты тестирования в течении секунд и не отвлекаться на рутину, есть nodemon. Это npm-пакет, который скармливает ноде js/coffee скрипт на старте и каждый раз при изменении отслеживаемых файлов. В итоге я узнаю о результатах тестирования каждый раз при сохранении файла.
![tmux-vim-nodemon](https://habrastorage.org/files/3f8/ff3/cf6/3f8ff3cf61ad459691c7811f6c990e37.png)
Для получения такой живой второй вкладки на ней запускается что-то вроде:
nodemon run-all-my-tests.coffee --watch my-changeable-files/*2
Сетап 3 — Clojure
Эта публикация не появилась бы, если бы не наткнулся какого-то парня, описавшего свой сетап.
Также для Clojure есть vim-fireplace, который среди прочего умеет доставать документацию.
Я предпочел vim-slime по одной простой причине — REPL.
Кложуровский REPL-сервер (nrepl) и клиент (REPL-y, идет в комплекте с Leiningen) сами по себе умеют уйму полезных вещей. Поведение vim-slime максимально примитивно и предсказуемо. Более того, когда REPL-y бежит в соседней вкладке, вы видите все историю и трейсы ошибок, а помимо самих возможностей REPL-y доступен еще и функционал tmux по работе с текстом. Вы можете переключится в REPL и исполнить там то, что не хотите писать и стирать в виме, и переключиться обратно.
![tmux-vim-clojure](https://habrastorage.org/files/66c/dd7/e22/66cdd7e2270b4bc78626c62aaaa8856f.png)
В целом опыт с Clojure REPL тот же, что и с NodeJS. Основное отличие от NodeJS REPL в том, что у Clojure REPL есть понятие пространства имен. Поэтому каждый раз, когда вы хотите послать в REPL конкретный кусочек кода, то приходится умудряться еще и переключить пространство имен. Это можно автоматизировать добавив в .vimrc:
function! SendNs ()
let cpos = getpos('.')
exec "1 SlimeSend"
call setpos('.', cpos)
endfunction
autocmd BufWinEnter *.clj :call SendNs()
autocmd TabEnter *.clj :call SendNs()
Таким образом, при каждом переключении вкладок в REPL выставляется текущее пространство имен. Должно быть указано первой строкой в файле. Скорее всего это можно автоматизировать более элегантно.
Оставшиеся плюшки и мелочи
Bash & SSH
Меня до сих пор приводит в детский восторг возможность открыть на соседней панели ssh-соединение с Штутгартом (hetzner) и передавать туда текст из Москвы. Таким образом, можно одновременно писать код и отлаживать удаленно. Также эта штука работает и с bash. На скриншоте в левой руке локальный vim, в правой руке удаленный bash:
![tmux-vim-bash](https://habrastorage.org/files/d84/b3d/201/d84b3d201a71445abfa5844db97fdf5c.png)
tmuxinator
Чтобы упростить создание tmux-сессий, я использую руби-проект тмуксинатор.
Мои .vimrc и tmux.conf
1. .vimrc
2. .tmux.conf
Почет
Нельзя не упомянуть хабровчанина-минималиста d3m1gd, сделавшего свой vim-slime. Также хочется сказать спасибо всем просветителям, рассказывающим о vim, tmux, и других *-NIX инструментах.