← Архив: Common Lisp

редактор oduvanchik

Author: · 14.07.2015 01:46
· original author: den73
Хочу сделать альтернативный емаксу клиент swank-а, написанный на лиспе, на базе phemlock,
который я переименовал в oduvanchik.
Репозиторием пока не порадую. Планирую делать его работающим не только под юниксы, но и под винду.
Выкинуть всё лишнее (dired, почту, проверку орфографии).
По правде сказать, пока не знаю, воплотится ли вообще этот план или нет. Это во многом зависит и от вашей поддержки.
Конечная цель - создание IDE для лиспа под лицензией MIT. Из понятных лисперу плюшек - возможность интегрировать IDE в ваш лисп-образ
без потребности в открытии портов и установке емакса, отсутствие необходимости использования убогого емакс лиспа.
Также хочется переработать логику работы команд емакса - очень уж она убогая, минибуффер, ctrl-g и всё такое прочее.
Но это, по правде сказать, уже изрядно тяжёлая задачка, поэтому она пока в области мечтаний
· original author: den73
Вот сделал репозиторий. Послезавтра в поход, вряд ли что-то успею сделать существенное. Код в данном репозитории не пытался собирать - вряд ли он соберётся и будет работать.
https://bitbucket.org/budden/oduvanchik
· original author: den73
На данный момент пытаюсь собрать (чтобы работало) под Linux/SBCL. Возник ряд трудностей, но пробиваюсь.
Также пришла в голову светлая мысль, что нужно взять за основу работающий с терминалом hemlock из CMUCL, а не
неработающий phemlock.
В связи с этим начал пытаться установить cmucl.
· original author: den73
В общем, есть оказывается hemlock, работающий с SBCL. В связи с этим одуванчик пересоздан заново.
Терминальная версия работает как-то слишком криво, если это вообще можно назвать словом "работает".
Поэтому взял за основу версию под CLX. За вчера и сегодня научил её открывать файлы в кодировке utf-8,
показывать Русские буквы и принимать их с клавиатуры (пока принимает только одну букву "ю").
На очереди клиент SLIME. В нём, правда, целых 7000 строк, но надо сделать хотя бы "proof of concept".
Репозиторий там же, хотя смотреть пока особо не на что. Разработка идёт под Linux.
· original author: lithp
Просто мысль:  почему бы не выкинуть CLX, и взять termbox, который хорошо работает на виртуальных юникс терминалах и также в виндовой консоли?   Было бы очень портабельно.
https://github.com/nsf/termbox
· original author: lithp
> В общем, есть оказывается hemlock, работающий с SBCL.
А можно ссылочку на репу?  Спасибо. :)
· original author: lithp
> Выкинуть всё лишнее (dired, почту, проверку орфографии).
Хочу емакс на CL :)
· original author: lithp
Ок, репу нашел git@github.com:bluelisp/hemlock.git
· original author: den73
Тебе нужен полный емакс со всеми плюшками? До этого, думаю, далекооооо.
Если бы задача стояла так, я бы взялся за написание транслятора elisp->cl. Но из-за лицензии на EMACS, к-рая мне не нравится,
я взял именно этот hemlock. Я хочу делать IDE для лиспа, например, чтобы распространять свои программки вместе с этой IDE.
Очевидно, что IDE под GPL для такого случая не всегда годится.
termbox - задумка на вид хорошая - в перспективе хочу отказаться от CLX. Но сейчас основной вопрос не в этом, работает как-то и ладно.
Емакс и SLIME сами по себе мало завязаны на графику. Я хочу сделать в первую очередь клиента для swank.
Если это удастся, то перевести графику на другой движок кажется делом не особо сложным.
Я вообще хотел использовать эмулятор консоли conemu для винды, а под линуксом тупо обычный терминал. Тогда получится обойтись
без всяких прослоек.
· original author: lithp
> Тебе нужен полный емакс со всеми плюшками? До этого, думаю, далекооооо.
Мечты :)
> Очевидно, что IDE под GPL для такого случая не всегда годится.
Согласен.  Нужна минимальная _удобная_ IDE для встраивания.
Поковырял я тут hemlock из репы (которая в quicklisp).  TTY бакенд вообще не завелся, падает в дебагер при старте.  CLX вроде запускается, но сыплет ошибками про неопределенные функции, например при комплите.
· original author: den73
До комплита далеко мне ещё - не смотрел его. Но зато научился кое-как вставлять кириллицу. Только строчные буквы и без № и прочих Shift-N.
Заодно убедился, что файлы в utf-8 не только открываются, но и сохраняются.
Весь этот hemlock весьма сырой. Но думаю, можно реанимировать, если навалиться толпой хотя бы из двух человек.
Ща залью в свой реп последнюю версию.
· original author: den73
У меня терминальная верия "работает", но нужно несколько раз нажать пробел. Тогда она прорисовывается. И потом реагирует с запозданием в одну букву. Естественно, запускать её надо не из под SLIME, а из обычной консоли (можно из графической). 
· original author: den73
Не люблю я метания, но тут что-то без них не получается.
Возникли некоторые проблемы.
1. slime.el - довольно большой файл - его переписывать порядка месяца.
А в итоге мы получим всего лишь текстовый интерфейс.
2. есть проблема с лицензией GPL на slime.el - не очень понимаю, как её обойти. Видимо, нельзя тупо взять и перевести
на Common Lisp - это будет, скорее всего, нарушением GPL. А с этого не хочется начинать.
3. hemlock нужно ещё допиливать до нормальной работы даже в CLX. Я уже поправил одну багу, а сколько их ещё впереди?
4. hemlock использует iolib. Насколько я смог понять, эта библиотека игнорирует существование windows.
5. Попытка создать slave процессы не была слишком удачной. Во всяком случае, мне не удалось создать slave thread.
Зато я нашёл able
У него куча достоинств:
1. Файл под лицензией MIT, у него сразу есть настоящий гуй на tk.
2. Сразу поддерживает кириллицу.
3. Интерпретатор лиспа сразу работает.
4. Есть главное меню!
5. Есть даже раскраска синтаксиса.
6. Сразу должен работать под виндой (хотя у меня не работает, но это нюансы, во всяком случае не CLX)
7. Объём исходников на порядок меньше!
Конечно, недостаток в том, что в проект тянется tcl. Но tcl/tk мне нравится. То, что в ANSYS гуй написан на tk, вполне убеждает в серьёзности данного тулкита.
Да и вообще на вид вполне ничего. Не нравится только ltk из-за лицензии, но это можно решить, я так думаю,
сделав свой более простой интерфейс к tcl/tk, который не отображает сущности tcl/tk на сущности лиспа, а тупо гоняет текст туда-обратно.
В этом случае напрашивается план, что мы не переписываем slime.el, а просто делаем графический интерфейс для отладчика - бекенд swank
- это public domain.
· original author: lithp
> hemlock нужно ещё допиливать до нормальной работы даже в CLX. Я уже поправил одну багу, а сколько их ещё впереди?
Я все таки попытаюсь запилить termbox backend в hemlock, просто ради спортивного интереса, к тому же у меня биндинги для LW уже есть.
> есть проблема с лицензией GPL на slime.e
А я почему то всегда думал, что он под MIT-like :(
> Зато я нашёл able
А он емаксо-образный?
· original author: den73
slime.el - под GPL, swank - public domain. Видимо, slime.el заразился лицензионным вирусом.
Правда, я нашёл вариант SLIME под vim, http://www.vim.org/scripts/script.php?script_id=2531
- там всё вроде чисто, не считая того, что сам vim под GPL вроде бы.
able - не емаксообразный, с моей точки зрения это хорошо.
· original author: lithp
Взглянул в код hemlock'a: боже мой, куча всякого неподдерживаемого крафта, закоментированного кода :) slave-mode который ты упоминал -- он просто не реализован для sbcl :)
A TTY backend у меня так и крашится при старте с мусором в терминале.
· original author: den73
Да, он так просто не запустится. Даже не знаю, с чего там начинать. Я бы начал с того, что выпилил iolib - всё равно его под виндой нет.
Я как раз сегодня разобрался немного в работе swank. swank идёт простым путём: создаёт кучу тредов, один читает, другой пишет, третий выполняет,
четвёртый делает flush каждые 0.2 секунды и т.п.
А hemlock полагается на мультиплексирование ввода-вывода, видимо, без большого успеха.
Тебе вообще больше нравится емакс или "не емакс"? У меня одна из задумок сделать что-то вроде 1С с конфигуратором, но для этого нужны простые решения.
EMACS не пойдёт. Другая практическая задача, к-рую я решал - расчёт двигателя Стирлинга. Опять же по здравому рассуждению я пришёл к выводу,
что мало кто сможет осилить EMACS. Поэтому я выбрал "не емакс", а с хемлоком стал возиться просто от нищебродства.
· original author: m4
Пришлось сегодня вновь воспользоваться услугами DrRacket, и как обычно моя психика подверглась испытанию на прочность. А причина всему - gc, точнее регулярно повторяющиеся stop-the-worldы! Как ide он всем хорош (emacs+geiser (аналог slime) даже рядом не стоит), но когда происходит stop-the-world, то появляется желание послать его куда подальше.
Я конечно же не хочу портить вам боевой настрой, но всё же и вашему ide скорее всего не избежать клятых stop-the-worldов.
· original author: den73
Ничё страшного. Иде лиспворкса и EMACS работают со сборкой мусора и ничего. Это не теория, а опыт (так скажем, многолетний).
· original author: m4
Я подозреваю, что у лиспворкса отсутствует песочница, поэтому ide там скорее всего является отдельным (независимым) процессом, т.е. имеет место клиент-серверная архитектура. Тогда как у вас ide будет встроено в приложение, или я не прав?
· original author: lithp
Нет, в лиспворксе ide прямо в образе сидит.  Проблем тоже не замечал, все быстренько работает.  Насчет ракетки, возможно это и не проблемы Гц, а кривой код ide.  На Джаве интерпразные ide запускают же.
· original author: lithp
Если выпиливать iolib из hemlock, тогда придется архитектуру менять на многотредовую (что мне подходит) или делать все на каком нибудь кроссплатформенность libev. 
Мне больше емакс по удобству и keystrokes нравится :). В мечтах минимальный работающий в консоли емакс лайк редактор полностью на CL, а там уж может народ подтянется и плагины будут.
· original author: m4
Код может и кривой, там всё на классах реализовано, что не может не сказываться производительности. Проблема в том, что при включенной трассировке стека, активных режимах отладки и профилирования (ещё можно подключить дополнительные синтаксические тесты), а также при использовании нескольких плагинов (расширений ide), отладить какой-нибудь сложный проект достаточно проблематично, т.е. приходится отлаживать (или тестировать) проект по частям (у меня даже появился свой собственный стиль проектирования программ с активным использованием смешанных классов и юнит-тестов). Конечно, если все это отключить, то никаких ощутимых зависаний не наблюдается. Но тогда становится проблемным локализация места (или причины) возникновения ошибки, ибо макросистема рэкета уж дюже наворочена. Так что в этом случае придется красноглазить.
· original author: den73
Многотредовая подходит или не подходит? iolib надо выпиливать, если нужна винда, тут без вариантов.
Я тоже раньше хотел терминальный. И сейчас сомневаюсь. Всё же довольно интенсивный обмен информацией между фронтендом и бекендом редактора нужен для подсветки синтаксиса и автоотступов. Это может свестись к необходимости на каждое нажатие клавиши посылать большой кусок текста (возможно, весь текст буфера целиком) в бекенд. Это может оказаться слишком накладно. Программировать же это на tcl - ещё хуже.
С другой стороны, мне кажется не особо сложным сделать графические инструменты как в Lispworks. Они будут удобнее текстовых. Также я считаю верхнее меню исключительно полезной штукой.
Нашёл тут ещё Turbo Vision. Как я понял, он под открытой лицензией. Когда-то я на нём несколько строчек написал...
· original author: lithp
Многотредовая подходит или не подходит?
я бы выбрал треды :)
 И сейчас сомневаюсь.


Почему?  В приведеном мной termbox библиотеке работа осуществляется с буффером, а не последовательно.  То есть можно куски текста битмаппить просто копируя память.  Должно быть быстро, и, что главное, портабельно.

Всё же довольно интенсивный обмен информацией между фронтендом и бекендом редактора нужен для подсветки синтаксиса и автоотступов.
>  на каждое нажатие клавиши посылать большой кусок текста (возможно, весь текст буфера целиком) в бекенд . Это может оказаться слишком накладно.


Только же для видимой области?



DISCLAMER: Я не спец в написании редакторов текста (давно было: писал для сдачи экзамена в университете простейший редактор в ncurses :) 




· original author: lithp
> Это может оказаться слишком накладно.
Тут вон даже на ерланге емакс пишут :)
https://github.com/5HT/pie
· original author: den73
Моя текущая концепция состоит в том, чтобы минимально завязываться на выбор гуя и максимально писать на лиспе.
Но редактор должен (на мой вкус) иметь "современный вид".
Наилучший гуй, к-рый я пока что нашёл - это tcl/tk. Он прост, переносим и хорошая лицензия.
Для редактирования лиспа нужно уметь раскрашивать текст и выставлять отступы. Писать этот код на tcl - маразм.
Значит, нужно передавать текущее состояние буфера в лисп, в лиспе его "раскрашивать" и обратно передавать раскраску в tcl.
Тут-то и можно влететь на большой объём передачи данных. Это случится тогда (если) не удастся инкрементно передавать
изменения текста в буфере в лисп. Вероятность тому довольно большая - для инкрементной передачи нужно отловить все изменения в буфере.
Передавать нужно не только видимую область, я так думаю. Опять же из-за необходимости точной синхронизации. Ведь чтобы правильно раскрасить текущий экран, нужно знать,
нет ли в начале файла какого-нибудь открывающего комментария.
Впрочем, я уже придумал выход: можно встроить tcl/tk в лисп с помощью FFI. Передача через FFI будет достаточно быстрой,
чтобы забыть об этой проблеме.
Конечно, остаётся неуютное чувство от необходимости привлекать "чужой" язык. Но пока не вижу выхода.
Но этим, конечно, нужно заниматься только тогда, когда это станет узким местом.
· original author: den73
Выложил планы по одуванчику вот сюда:
https://bitbucket.org/budden/oduvanchik/wiki/Roadmap
В принципе, если будут попутчики по его развитию и сможем согласовать планы, то может быть я брошу затею использовать tk и можно остаться в рамках одуванчика.
В емаксе мне не всё нравится. Например, я считаю, что поиск должен происходить через диалоговые окна, как это принято в современных редакторах, а не через 8 команд.
Я бы интегрировал REPL и строку команд в единое целое, раз уж у нас "встроенное" IDE. Честно сказать, дизайн редактора - это целая отдельная область деятельности, дизайн емакса мне не нравится, а как его
исправить - я не знаю. Так что тут надо бы взять дизайн какой-то современной среды разработки и просто его содрать без особых обсуждений. Я работал в средах
борланда, они мне привычны, хотя им явно недостаёт командной строки.
· original author: flyamt
> Значит, нужно передавать текущее состояние буфера в лисп, в лиспе его "раскрашивать" и обратно передавать раскраску в tcl.
> Тут-то и можно влететь на большой объём передачи данных. Это случится тогда (если) не удастся инкрементно передавать
В Tk-шном text - блочно-теговая модель.
> Впрочем, я уже придумал выход: можно встроить tcl/tk в лисп с помощью FFI.
cl-tk (BSD)
> Конечно, остаётся неуютное чувство от необходимости привлекать "чужой" язык. Но пока не вижу выхода.
В принципе нужен только Tk-шный интерфейс. Знание самого tcl при этом практически не требуется. На CyberForum-е товарищ делал более совершеный вариант, может есть смысл спросить у него наработки.
Смотрел на swank-protocol (MIT) ?
· original author: den73
Спасибо, любые поинтеры на релевантный код приветствуются, но в случае swak-protocol пользы мало: ибо здесь всего 261 строка, а в slime.el - 10000. Явно чего-то не хвтатае :)
Прошу прощения за мой русский, сейчас сижу и пытаюсь вызвать лисповый eval для строчки, взятой из виджета text, всё это на cl-tk.
Не пойму, можно ли при отправке события передать в лисп какие-то сопутствующие данные и если да, то как. Документация, так скажем, скромная.
Поэтому голова немного забита.
Хотя как отправную точку можно принять.
Насчёт киберфорума вообще не понял, что они хотели сделать. Если хотели оболочку на секспах для tcl, то я лучше tcl выучу - не так-то он и страшен.
Или они что-то ещё хотели?
· original author: flyamt
> Не пойму, можно ли при отправке события передать в лисп какие-то сопутствующие данные и если да, то как. Документация, так скажем, скромная.
Есть -data и %d для отсылки и приема соответственно. Но зачем тебе это надо и надо ли вобще, без контекста не ясно :(
· original author: flyamt
> но в случае swak-protocol пользы мало: ибо здесь всего 261 строка, а в slime.el - 10000. Явно чего-то не хвтатае :)
Там очередь и декодинг сообщений. Остальное в соселнем проекте под лицензией которая тебе не понравится.
> Если хотели оболочку на секспах для tcl
Ну я думал про это когда предлагал. Хотя cl-tk еще и "мусорные" обрабочики не собирает.
· original author: den73
Да, нашёл уже -data, пытаюсь прикрутить, пока основная проблема в том, что сокет не закрывается.
Редактор рулит лиспом через сообщения в своём главном цикле. В частности, сейчас для примера хочу
взять из видгета text его текст и заставить лисп сделать eval - всё это по выбору пункта меню в редакторе.
Нужно не просто сказать лиспу "чебурашка, приборы", а передеать строку для выполнения. Как это сделать?
Я вот и хочу для этого data приспособить.
А сокет мне нужен, чтобы лисп мог что-то пропищать редактору асинхронно. Соответственно, tcl ловит его через fileeevent.
Не знаю, не лишний ли сокет в этой схеме? И не наступлю ли я на какие-то грабли, связанные с cffi и тредами (было там что-то нехорошее
про коллбеки).
Контекст будет, когда будет версия хотя бы 0.0.1, нечто законченное до такой степени, чтобы имело смысл создавать репозиторий. Пока же полная неясность.
· original author: flyamt
> взять из видгета text его текст и заставить лисп сделать eval
(tcl  ".text_path" "dump" "1,0" "end") вернет текс с разбивкой по блокам (теги, отметки)
(tcl  ".text_path" "dump" :command calback_id "1,0" "end) будет скормливать функции текст поблочно
(tcl  ".text_path" "get" "1,0" "end") просто вернет строку
> всё это по выбору пункта меню в редакторе.
:command callback_id
> Нужно не просто сказать лиспу "чебурашка, приборы",
Не понял юмора и смысла:(
> А сокет мне нужен, чтобы лисп мог что-то пропищать редактору асинхронно. Соответственно, tcl ловит его через fileeevent.
Ты делаешь что-то ужасное. Почему тебя не устраивают обычные нити?
· original author: den73
Наверное, тем, что я не знаю, как их готовить.
Нити в tcl? Или ты хочешь сказать, что я могу вызвать из другого лиспового треда cl-tk:ltk, в то время как исходный тред "завис" на обработке (cl-tk:mainloop)?
Это не очевидно, что можно. Даже не понятно, где про это можно прочитать.
· original author: flyamt
> в то время как исходный тред "завис" на обработке (cl-tk:mainloop)?
Когда придет событие для зарегистрированного обработчика mainloop передаст ему управление и оттуда можешь вызывать (tcl ... "dump" ...). В твоем случае это обработчик который создаешь через event-handler и передаешь как аргумент :command при добавлении пункта меню. Это обычный путь
· original author: flyamt
Сам по себе cl-rk:mainloop это обычный cl:loop который общается с Tk через cl-tk:doevent. Соответственно закат солнца вручную со  стороны лиспа для особых потребностей.
· original author: flyamt
Ненаучный метод. (tcl "after" <время-в-мс> callback-id) и переустановка в обработчике этого заново. Таким нехитрым способом уже сам Tk ,будет запрашивать у лиспа ""Что делать будем?"
· original author: den73
> Когда придет событие для зарегистрированного обработчика mainloop
Когда придёт - это хорошо. Но как я из лиспа сделаю, чтобы оно пришло? Вот я для этого открываю сокет и пишу в него со стороны лиспа, а на стороне tk - fileevent. Кстати, уже почти готово, надеюсь сегодня выложить реп.
after - это ламерство какое-то :)
· original author: den73
А есть событие "exit"? Хочу на нём сокет закрывать. Достал уже этот сокет.
· original author: flyamt
bind . <destroy> чего-то
· original author: flyamt
> Но как я из лиспа сделаю, чтобы оно пришло?
Ты доки к cl-tk читал ? :),(:
(tcl "ttk:button" :text "Exit" :command (event-handler #'destroy))
перед вызовом mainloop
Если действия у тебя самозарождаются непредсказуемым способом, то смотрим на нерасширяемую реализацию mainloop-а из 3 строчек
(defun mainloop ()
    (loop :while (alive-p)
    :do (doevent t)))
и делаем как правильно и как нравится
· original author: den73
Доку cl-tk осилил :)
В примере, нарисованном тобой, событие зарождается в tk, а в лиспе обрабатывается.
Если я ушёл пить кофе, а у меня за это время лисп досчитал (sleep 1000), то он должен как-то сказать редактору,
что нужно нарисовать в typescript буфере ">". Т.е., тут событие зарождается в лиспе, и его нужно обрабтат ь в tk.
Данный mainloop тут ничем не поможет, т.к. он просто "висит", пока я пью кофе и не жму кнопки в tk.
Поэтому (складывается чувство), что сокет я приделал не зря.
Пока сделал фронтенд wish, потом верну в ffi, задолбал сокет.
Как окошко озаглавить?
· original author: flyamt
wm title . <заголовок>
· original author: flyamt
> Данный mainloop тут ничем не поможет, т.к. он просто "висит", пока я пью кофе и не жму кнопки в tk.
(doevent nil)
не висит
> Поэтому (складывается чувство), что сокет я приделал не зря.
Ну каждый сходит с ума по-своему.
· original author: den73
Спасибо! Уже почти-почти-почти. Научился забирать текст, осталось отправить его в лисп. Ща попробую %d задействовать...
Насчёт с ума портом разберсь.
· original author: den73
А doevent nil не завесит ли гуй?
· original author: flyamt
(doevent t) заблокирует поток и будет ждать сообщения. (doevent nil) проверит наличие необработаного события и если ничего найдет отдаст управление. И они оба завершаться после обработки одного события. Живость обеспечивается циклом в mainloop-е или его заменителе. Если просто заменить t на nil то наличие события будет проверятся в 100500 раз чаще на стороне лиспа.
· original author: flyamt
Вобще в нутрях tcllib есть более осмысленый способ добавлять внешние источники событий, но там больше C-шно/FFI-шной магии.
· original author: den73
Ну чё, я научился с твоей помощью передавать строчку в лисп и синхронно вызывать eval. Но правда возвращаемое значение плохо пока передаётся.
Никак не передаётся.