Pull to refresh

Нездоровый минимализм: ide

Abnormal programming *
При программировании на common lisp стандартной средой разработки является SLIME. Пожалуй единственным главным недостатком SLIME является emacs, особенно для поклонников vi. Конечно же есть поделки и для vim, но сам vim тоже не верх минимализма.

Под катом минимальный ide для интерпретируемых сред без блэкджека и шлюх.


Что понадобится:
  • Беглое знакомство с tmux
  • Сам tmux
  • Программа-интерпретатор любимого ЯП
Кто знаком со screen, но не знаком с tmux: отличия в официальном FAQ (EN), кто не знаком ни со screen, ни с tmux: мини вступление в tmux (EN). Для тех, кому не нравится английский язык — wikipedia (RU).

— Чем плох screen?
— Тем, что он GNU и кроме того не может делить окно по вертикали.

Концепция


Главная проблема работы с чистым интерпретатором — необходимо каким-либо образом сохранять код (при условии что он за вас это не делает). Решается довольно просто:
  1. открываем терминал с интерпретатором
  2. открываем текстовый редактор
  3. набираем код в редакторе
  4. копируем в терминал
  5. смотрим результат, радуемся/огорчаемся
Код сохраняется в редакторе. Так жить можно, но грустно. Надо бы автоматизировать. Используем tmux, а в помощь ему напишем пару простых скриптов.

Реализация


#!/bin/sh
# скрипт ide
interpreter="sbcl"
windowname="ide"
ide_running=`tmux list-windows | grep "$windowname"`

if [ "$TMUX" ]; then
   if [ "$ide_running" ]; then 
      tmux select-window -t "$windowname"
   else
      tmux rename-window "$windowname" \; split-window -dhp 40 "$interpreter"
   fi
else
   if [ "$ide_running" ]; then
      tmux attach-session \; select-window -t "$windowname"
   elif tmux has-session >/dev/null 2>&1; then
      tmux attach-session \; new-window  -n "$windowname" \; split-window -dhp 40 "$interpreter"
   else
      tmux new-session -n "$windowname" \; split-window -dhp 40 "$interpreter"
   fi
fi


#!/bin/sh
# скрипт idepipe
tmpfile=`mktemp /tmp/tmuxbuffer.XXXXXX`
tee $tmpfile
tmux load-buffer $tmpfile >/dev/null 2>&1
tmux paste-buffer -dt 1 >/dev/null 2>&1

rm -f $tmpfile

Первый скрипт запускает/восстанавливает сессию tmux с окном ide и двумя панелями. В левой консоль, в правой — интерпретатор из переменной $interpreter. В консоли запускаем любимый текстовый редактор. В BSD системах vi клоном по умолчанию является nvi. Вполне подходит, его и запустим.



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

Примеры


Common Lisp


Кладем скрипты в $PATH, запускаем ide. В текстовом редакторе vi наберем произвольный код. Когда он будет выглядеть достаточно качественным, набираем комманду :%!idepipe. Для тех кто не знаком с vi следует пояснить: двоеточие начинает комадну, % означает весь файл, idepipe — имя фильтра. На человеческом языке это будет звучать так: выдать весь буфер на вход команды idepipe и перезаписать весь буфер тем, что получим на выходе. Ясное дело, что код изменять мы не хотим, поэтому внутри idepipe используется tee. Если все получилось как планировали, то в окне интерпретатора окажется весь желаемый код, а также результат его выполнения. Для выполнения всего кода последняя линия в файле должна быть пустой, иначе необходимо самому нажать enter в окне интерпретатора.



Кроме знака % можно использовать еще много адресных обозначений. Таким образом в интерпретатор можно посылать только часть кода (которую изменили), без необходимости вновь переваривать весь файл.
:10,30!idepipe — интерпретировать все между 10 и 30 линиями, включительно
(!)idepipe (без двоеточия) — интерпретировать один lisp блок
Более того, нет необходимости каждый раз набирать эти команды, достаточно один раз их замапить.
:map {ctrl-v}{F3} {ctrl-v}{esc}(!)idepipe{ctrl-v}{enter} — интерпретируем блок кода по нажатию F3
:map {ctrl-v}{F5} {ctrl-v}{esc}:%!idepipe{ctrl-v}{enter} — интерпретируем весь файл по нажатию F5
На месте фигурных скобок необходимо нажимать соответствующий клавиши
Обе команды действуют в том числе и из режима редактирования
— А будет работать с другими интерпретаторами.
— Должно работать с любыми REPL окружениями (Read Eval Print Loop). Проверим еще пару.

Python



Питон я запускаю впервые, поэтому код не слишком хитрый, зато работает.

Shell




Кроме того должны работать mysql, irb, и др.
— Выглядит неплохо, но все же хочется карт и девочек.
— Не проблема. Добавляем мега фичу.

Мега фича


Для начала изменим скрипт idepipe.
#!/bin/sh
# скрипт idepipe
tmpfile=`mktemp /tmp/tmuxbuffer.XXXXXX`

tee $tmpfile
tmux load-buffer $tmpfile >/dev/null 2>&1
tmux paste-buffer -t 1 >/dev/null 2>&1
tmux paste-buffer -t 2 >/dev/null 2>&1
tmux paste-buffer -dt 3 >/dev/null 2>&1

rm -f $tmpfile
Ого, целых две новых строки. Какой уж тут минимализм. Что же дает данное изменение? Все очень просто: вместо одного интерпретатора мы можем посылать код сразу на три. На невысказанный вопрос «зачем?» ответ очень прост: разные реализации языка common lisp имеют несовместимости. Проверяя код сразу в трех интерпретаторах — убиваем двух трех зайцев.

disclaimer: idepipe написана без какой-либо защиты от дурака, поэтому во избежание странного поведения tmux надо вручную создать две дополнительных панели на окне ide и запустить в них интерпретаторы. Номера панелей интерпретаторов (как видно из скрипта) должны быть 1, 2 и 3.



Итак, момент X. Выполняем знакомую команду (!)idepipe над одной из функций и наблюдаем выполнение кода в трех разных интерпретаторах. This is WAY cool! Одной фичей и ограничимся, минимализм требует.



Порция нездорового минимализма


Любимый текстовый редактор трЪ гиков — ed. Кто бы мог подумать, что ed подходит для этой статьи, а ведь подходит. Он и минимальный, и текст в пайп передавать умеет. Что еще надо для счастья? Выполняем 12,13w !idepipe и результат появляется во всех панелях.



Thanks

Оригинальную идею почерпнул из плагина для vim.
Tags: минимализм
Hubs: Abnormal programming
Total votes 37: ↑34 and ↓3 +31
Comments 16
Comments Comments 16

Top of the last 24 hours