-- Leo's gemini proxy

-- Connecting to hugeping.ru:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

Каждый программист должен написать свой редактор

by hugeping on 2023-09-10 11:32:09


Решил написать небольшую заметку про свой новый проект. Интересно, что как и остальные, он стал эволюцией моих прошлых экспериментов. Занимаясь INSTEAD я полюбил Lua. Играя с Plan9 я сделал парсерный re:instead (в том числе и для того, чтобы можно было писать парсерные игры прямо в Plan9). Развил re:instead в rein, который стал уже скорее "платформой" приложений.


Не смотря на то, что rein создавался с мыслью о "духе ретро", я не стал выбрасывать из него функции, которые бы позволяли писать "полноценные" приложения. Например, поддержку шрифтов ttf и возможности менять размеры окна на лету. Я знал, что рано или поздно я попробую сделать это -- написать свой собственный текстовый редактор. :)


Я пользовался разными редакторами. Среди них, конечно, особое место занимают vim и emacs. Но когда я познакомился с acme я понял, что по большому счёту совсем не важно в чём ты пишешь код. Простой инструмент может быть гибким, эффективным и вдохновляющим.


У кого-то может возникнуть вопрос. А почему я не использую vscode? Потому что моя профессия приносит мне удовольствие и я разборчив в своих предпочтениях. Что касается vscode:


- это приложение на основе браузера;

- vscode пришёл из недр корпорации.


Как я обхожусь без "фишек" современных редакторов? Наверное, мне они не так уж и нужны. Даже наоборот, вылезающие подсказки во время набора раздражают. А после acme я осознал, что и "раскраска" текста -- какая-то ненужная нелепость. Играет роль и то, что в моей области деятельности не нужно запоминать бесчисленное число методов и классов. Я могу писать код просто "из головы".


Я начал проводить всё больше времени в acme, написал для него e-mail клиент, но всё-таки нельзя сказать, что он стал моим единственным редактором. Он является естественным в своей родной среде обитания - Plan9, но для работы в Linux/Bsd* необходимо собрать plan9ports. Я не чувствовал, что инструмент "принадлежит" мне в полной мере.


Так что мысль о собственном _простом_ редакторе стала приходить мне всё чаще. Наверное ещё во время работы над re:instead (который был написал под вдохновением от редактора Lite) я увидел, что это возможно.


Потом, в rein я написал простой "традиционный" редактор edit и пользовался им при разработке под rein. Ощущение инструмента в котором ты знаешь каждый "болтик" было непередаваемым!


В edit (редактор rein) в начале было много багов. Файл в edit был представлен в виде массива строк. Это удобно для навигации и отображния, но совсем неудобно для редактирования. Пока я его дописывал и фиксил баги я подумал, а что если файл представлять не массивом строк, а просто -- одной строкой? И тут же снова вспомнил acme, где изменения высоты скроллера явно намекает на то, что в качестве позиции используется смещение, а не номер строки. Стало интересно попробовать. И в этот раз я не смог погасить свой порыв. Так я и начал писать свой мини-acme.


Многие фишки acme раскрываются в полной мере в Plan9. Например, файловая система, через которую можно управлять редактором. Да, в Linux тоже можно монтировать её через fuse, но есть нюансы, которые делают этот метод не рабочим. Поэтому я был настроен делать именно "мини"-acme редактор, в котором мог бы делать свою повседневную работу. В качестве механизма расширения - конечно Lua!


Сейчас редактор доведён до полу-готового состояния и смержен в master ветку проекта rein. Редактор делается под мои предпочтения, поэтому он не будет демонстрироваться "широкой" публике, но я всё-таки решил написать этот текст на случай, если им заинтересуется кто-нибудь ещё.


Итак, особенности редактора red.


RED -- Rein Editor


Клавиши


В отличие от acme в red работают многие привычные комбинации клавиш:


- ctrl-c/x/v - копирование, удаление, вставка;

- ctrl-z - undo;

- ctrl-k - удаление до конца строки;

- стрелки курсора - перемещение по тексту во всех направления;

- page down/up - перемещение по тексту по странично;

- home/end - начало и конец строки;

- ctrl-w - умное выделение;

- ctrl-s - сохранение буфера (окна).

- shift-движение - выделение клавиатурой.


Как в acme (или почти как в acme) работают:


- escape - выделение последнего блока, удаление;

- ctrl-f - автодополнение путей (правда, если варинтов несколько - выдаётся первый);

- ctrl-a - начало/конец строки.


Мышка


- аккорды acme - должны работать похоже;

- правая кнопка мыши - простой поиск как в acme;

- alt+правая кнопка мыши - простой поиск назад;

- shift + правая кнопка мыши - эмуляция средней кнопки мыши.


В отличие от acme курсор _мыши_ не прыгает на выделенный текст поиска (так как управление курсором из приложение возможно не во всех средах). Чтобы продолжить поиск нужно повторно кликнуть в пустую область где нет текста (например, справа от строки). Или кликнуть на слово для поиска этого слова.


- правая кнопка мыши на :число - прыжок на строчку.

- средняя кнопка мыши - выполнение действия: меню, вызов программ, открытие каталогов и файлов.


В acme открытие файлов и передача в plumber делается по пкм, однако это меня всегда немного раздражало. Потому что иногда клик приводит к поиску, а иногда - к действию. Захотел поискать https://... [1] в коде, а открылся браузер. Поэтому в red все активные действия висят на средней кнопки мыши. А открытие каталогов, файлов - это тоже активные действия. Возможно, я сделал ошибку, но пока решение кажется удобным.


- умное выделение


Не такое как в acme, но всё-таки удобное. Двойной клик справа от строки - выделить всю строку с переводом строки. Двойной справа от последнего символа строки - строка но без перевода строки. Клики около скобок - выделение до пары. Клики на словах - выделение слов. Кроме мышки можно пользоваться умным выделением нажимая ctrl-w.


Окна


Я отказался от деления столбцов на стек окон. Вместо этого в одном столбце может быть открыто несколько файлов. Причин две: это проще устроено и этим чаще проще пользоваться. Когда вы открываете ещё один файл в столбце, он становится активным, а предыдущий файл становится на позицию 2 в списке файлов в меню. Вы можете выбрать любой из ранее открытых файлов средней кнопкой мыши. При этом активный файл (который отображён в окне) станет на место выбранного файла. Этим свойством удобно пользоваться для закрытия всех файлов кроме одного. Просто сделайте нужный файл последним в списке, а потом нажимайте подряд Close пока не останется только он. Вы можете перетащить открытый файл в другой столбец если потащите пкм за квадратик меню в область другого столбца.


Когда вы открываете файл, то ищется уже открытый файл по всем столбцам и если он есть -- показывается. Если вам нужно открыть несколько одинаковых файлов, вам придется поменять имя открытому файлу в меню (напрмер, добавить "+" в начале) и открыть этот же файл ещё раз.


Если имя файла начинается с "+", то такой файл не сохраняется на диск. Поэтому информационные окна называются: +Errors, +Output, +Help и т.д. Вы можете любое окно сделать информационным просто добавив + в начало имени активного файла (первый файл в списке файлов в меню).


Скроллеры в отличие от acme работают традиционно - левая кнопка мыши "таскает" скроллер.


Вызов программ


Поддержки win (запуск шелла) на данный момент нет. Это связано с тем, что полноценную поддержку процессов нужно делать через fork. Это привяжет red к Unix. К тому же, red - это lite-acme. :) Расширения red можно делать на Lua, но для запуска полноценного shell этого недостаточно.


Возможности по запуску программ


- >cmd - запуск cmd с передачей в качестве параметра временного файла с данными;

- <cmd - запуск cmd с чтением stdout;

- !cmd - запуск cmd


Кроме того для Linux всё-таки доступна:


- |cmd - работает примерно как в acme. На вход через пайп передаётся текст или выделение и ждём выхода.


Всё это реализовано за счёт io.popen временных файлов и coroutine (переключение после чтения пачки строк). Поэтому - ненадёжно. Если вы запустите программу которая висит и ничего не выдаёт, red зависнет. Поэтому реализацию нельзя считать полноценной замену acme. Тем не менее, я пользуюсь этим механизмом для проверки орфографии.


Если запускается программа с параметрами, выделите всю строчку и нажмите среднюю кнопку мыши.


Встроенные команды


Основной механизм расширений редактора всё-таки не через запуск внешних команд, а за счёт написания процедур на Lua. Процедуры находятся в файле data/lib/red/proc.lua и на данный момент включают следующие команды:


- sub - поиск или поиск/замена построчно;

- gsub - поиск или поиск/замена глобально;

- select - синоним gsub без замены;

- find - синоним sub без замены;


Внимание! Все регулярки - регулярки на Lua!


Примеры:


select ^.*$ - выбрать всё

sub /^/ / - построчно добавлять в начало строки 4 пробела.


Во втором примере на каждые 2 клика вы получите одну итерацию: поиск-замена. Но если хотите произвести манипуляции не интерактивно - выделите текст, с которым работаете. Например:


gsub ^.*$ - выделили всё (тот же select)

sub /^/ / - отработали по выделению.


Доступна форма записи поиска с / - если нужно работать с пробелами:


select / / - выбрать 2 пробела.


Другие встроенные команды:


- Getline - добавляет справа от себя текущий номер строки. Удобно для составления "закладок" в файле;

- fmt [ширина] - аналог утилиты fmt;

- grep выражение - рекурсивный поиск по содержимому файлов каталога. Каталог - dirname открытого в данный момент файла;

- Run [программа] - запуск программы rein (интеграция для разработки под rein) или текущего файла.


Dump


При нажатии средней кнопки мыши на Dump - в текущем каталоге создаётся конфигурация сессии (файл red.dump). В сессии сохраняются все данные открытых файлов. Даже если вы сотрёте сами файлы, при восстановлении сессии они будут показаны в окнах. Если red находит в текущем каталоге red.dump он всегда его загружает. Возможно, в будущем появится опция для загрузки Dump.


Параметры командной строки


Запуск red:


$ rein red [-fs <размер шрифта>] [файлы]


Чтобы немного ускорить запуск можно воспользоваться опциями:


$ rein -platform-nosound -platform-nojoystick ...


Для удобства я делаю себе скрипт вида:


-- red

/home/peter/Devel/rein/rein -platform-nosound -platform-nojoystick red -fs 19 "$@"


И запускаю редактор из любого места.


Открытие файлов по средней кнопке мыши


В файле data/lib/red/uri.lua вы можете прописать вызов внешних программ. Например, запускать просмотрщик pdf если вы нажали на строчку, которая заканчивается на .pdf.


Настройки для типов файлов


В файле data/lib/red/presets.lua вы можете настроить поведение редактора в зависимости от типа файла (расширения). Пока доступны только размер табуляции и режим табуляции (пробелы или \t). Скорее всего появятся и другие настройки.


Цвета


В начале red.lua в таблице conf.


Что дальше?


Редактор ещё сыроват, но я начал его использовать и постоянно вношу доработки. Приоритет разработки - личное использование. Ведь вряд-ли вы захотите променять vscode на _это_! Не правда ли? :) Но меня это не беспокоит. Ведь теперь я точно знаю -- каждый программист должен написать собственный редактор!


У Линуса есть https://github.com/torvalds/uemacs [2] у Роба Пайка -- acme, у Столмана emacs. А у меня теперь есть red и мне больше не нужно выбирать!


P.S. Один мой друг удивился тому, что у меня есть желание программировать после работы и тратить время на такие вот хобби проекты. Не знаю в чём дело, но с годами желание программировать у меня никогда не исчезало. И я считал что это нормальное состояние для программиста. Программирование -- это в первую очередь форма творчества, а творчество всегда лечит. Ведь творчество это свобода. Эксперимент, игра -- но никак не рутина. В хобби проекте ты можешь почувствовать это в полной мере, ведь тут ты не ограничен целесообразностью. А на работе... На работе теперь можно будет редактировать код в red :)

https://... [1]

https://github.com/torvalds/uemacs [2]

-- Response ended

-- Page fetched on Wed May 1 03:16:12 2024