ну к примеру можно условиться о специальном файле, я думаю не сложно будет носить килобайтный файлик в проекте) или какой нибудь комментарий, найдя который в блоке кода, она будет скрывать этот код. Я думаю знатоку elisp будет пару минут накатать такой функционал
Долго объяснять. Самый быстрый вариант у меня получился такой: я тупо собираю нужные оверлеи по файлу, сохраняю координаты их начала в виде списка в файл с дополнительный расширением .hs (на каждый текстовый файл свой). Соответсвенно, при восстановлении иду по списку по сохраненным координатам и делаю в этом месте hide. Если спрятанных участков нет, то файл не создается. У способа есть недостатки, которые обусловлены недостатком режима.
Не тестировал! Пару раз попробовал, высылаю как есть.
Тупой способ использования ниже. Тупой, потому что при каждом скрытии блока обновляет файл состояния, однако это может происходить относительно быстро и не так анноить. Более интеллигентные варианты требуют времени (которого нет). Названия файлов для сохранения состояния можешь сам себе придумать.
Очевидный недостаток: переправил файл в другом редакторе — все поползло, так как рассинхронизация произойдет. Ситуацию можно чуточку, наверное, улучшить, если сохранять не начало оверлея, а скажем середину между overlay-start и overlay-end. Тогда, может быть, несколько вставленных переводов строки меньше скажутся на рассинхронизации. Второй недостаток (блин, очень много писать) - это то, что хук hs-show-hook вызывается при выходе из режима hs-minor-mode (так как автоматом вызывается hs-show-all), поэтому обновление файла в этом хуке я не делал (закомментировано в примере). То есть если ты раскроешь какой-то блок, то информация о нем не сохранится, пока ты либо не свернешь какой-то другой блок, либо ты вручную или по таймеру не вызовешь hs-save-state (типа автосохранения через промежутки времени). Короче, тут надо подумать.
Я думаю, что можно написать по-другому, это уже по ходу дела идейки пришли, но мне не хочется их делать. Можно базироваться не на оверлеях, а сохранять в хуке hs-hide-hook позицию, где ты попросил свернуть блок. Но тогда надо усиленно подумать, как удалять эту позицию, когда ты опять раскрыл блок. Ведь раскрыть блок ты можешь, находясь в другой позиции, которая отличается от сохраненной. Нужно подумать над алгоритмом, как правильно удалять из списка старые, ненужные позиции (можно использовать данные из оверлеев или диапазоны начало-конец сохранять).
Идея с тегами (специально составленными комментариями в тексте программы на языке программы) кажется разумной, потому что тогда не будет рассинхронизации. Но в тексте от этих тегов будет мусор. Можно еще как варинат рассмотреть возможность расстановки каких-нибудь реперных точек по тексту, а координаты запоминать относительно них.
Сегодня еще раз глянул, что написал. Оказалось, что в Emacs 22 хук hs-show-hook не работает как надо. По документации он всегда должен вызываться при toggle, hs-show-block и hs-show-all, а он вызывается только после hs-show-all. Глянул в исходники hideshow.el. Мне действительно кажется, что там баг. Хук там есть, но до него дела никогда не доходит, не срабатывает он у меня. Не знаю, исправлено ли что-то в последующих версиях Emacs.
Если хук работает сейчас в Emacs23/24, то его можно раскомментировать. Но при работе помнить одну только вещь — не выходить из режима при помощи выключения hs-minor-mode, не менять режим буфера, а просто закрывать буфер. Если выключить режим, то перед вызовом хука hs-minor-mode-hook всегда принудительно вызывается hs-show-all. Сделать с этим ничего нельзя (ну, если только хачить hideshow.el). Как отличить по косвенным признакам, ручное раскрытие всех блоков пользователем и финальное автоматическое раскрытие, я пока не придумал. Просто финальный автоматический вызов hs-show-all запишет текущие оверлеи, а они все уже будут удалены после hs-show-all.
И еще, возможно, лучше записывать в файл не начало оверлея, а (1+ (overlay-start ov)).
>Глянул в исходники hideshow.el. Мне действительно кажется, что там баг. Хук там есть, но до него дела никогда не доходит, не срабатывает он у меня. Не знаю, исправлено ли что-то в последующих версиях Emacs.
Я обширно не тестировал. Если какие-то баги заметишь, то, может быть подправим. Я этот код у себя оставил на всякий случай.
А может им в стандартную поставку это добавить?
Чтобы добавить такое, надо посерьезнее отнестись к делу, так как способов решения задачки может быть несколько (то же тегирование как альтернатива).
К тому же, сейчас я со своей стороны ничего не могу добавить в Emacs, так как для этого FSF требует подписания copyright assignment papers. Я месяц назад отправил запрос на бумаги, а они так и не пришли. Я попросил FSF подтвердить, что бумаги отправленв, а они, оказывается, запроса с заполненным вопросником не получили. Пришлось с другого ящика выслать. Надеюсь, что в этот раз получили. Теперь надо ждать, когда бумаги приедут сюда, потом я их подпишу, отправлю назад. Без этой процедуры никакие мои патчи в транк брать не будут. Берут только тривиальные патчи меньше 10 строк.
Вот баг уже выцепил. Если скрыть что-то, а потом просто отбить переводами строк (достаточно большим количеством), то Emacs это отслеживает, а вот в файл *.hs изменения не попадают. Соотвестственно, рассинхронизируется все. Надо пнуть Emacs, чтобы при изменениях сдампил снова. Разумно повесить hs-save-state на хук сохранения буфера. Если ты отбиваешь текст RETом или что-то добавляешь, то у буфера сразу поменяется флаг, что он был изменен. Это неизбежно заставит Emacs тебя предупреждать перед закрытием, что файл был изменен и надо сохранить, сработает хук и все новые значения координат сохранятся.
При этом можно даже отказаться от того, чтобы вешать на хуки hide и show сохранение *.hs (hs-save-state). Можно просто выставлять в этих хуках флаг, что файл в буфере изменен (то есть будем считать, что скрытие кода и раскрытие — это изменение. Не так кузаво, конечно, но зато в файл при каждом чихе дампить не надо будет). Тогда Emacs при закрытии буфера будет предлагать сохранить файл. Заодно и состояние hideshow сохранится. Вот тут надо подумать, есть ли смысл так делать.