Я использую Emacs с Geiser, чтобы взломать код Scheme. Играя в REPL, я иногда оцениваю выражения, которые приводят к значительному выводу, часто все в одну строку.
Например, я просто играл с SRFI-41 (потоки) и создал поток символов из большого файла; затем я заставил поток, и Гейзер скопировал все содержимое файла как поток символов в мой буфер. Практически сразу Emacs останавливается, поскольку все больше и больше символов добавляются в строку вывода, и независимо от того, как долго я продолжал нажимать C-g
или C-c C-c
не мог заставить Emacs (или Geiser) остановиться.
Это прервало весь мой сеанс Emacs, так как Emacs теперь полностью игнорирует мой ввод, думая, что ему нужно отдавать приоритет печати этого массивного потока символов в одну строку в неотвечающий буфер Geiser REPL.
Что я могу сделать, чтобы защитить сеанс Emacs от моего разрушительного любопытства? (Почему Emacs так медленно работает при отображении очень длинных строк?) Могу ли я установить ограничение для длинных строк и сказать Emacs, что можно просто не пытаться отображать очень длинные строки?
источник
yes
вansi-term
, например , имеет аналогичный (но не , что ужасный) эффекта. На самом деле, это просто объем текста, который дает паузе emacs.yes
в эмуляторе терминала VTE максимально использует все мои процессорные ядра, поэтому я бы не стал использовать его в качестве примера.Ответы:
Как уже отвечали в комментариях, Emacs очень медленно перерисовывает длинные строки - это хорошо известная проблема . Исправить это было бы очень хорошо, но нужно много мыслей, чтобы быть правильно вытащил. У меня есть представление о том, как это можно сделать, основываясь на разделе 6.3 этого документа (в основном, храните информацию о визуальных строках в текущем буфере и обновляйте ее при вставке пробела, свойствах отображения, изменениях окна и т. Д., Затем используйте эту информацию в код повторного отображения, чтобы не сканировать его все время), но я недостаточно знаком с внутренними компонентами Си, чтобы выполнить его.
Хотя есть обходные пути. Наиболее очевидными из них будут настройка параметров, связанных с отображением (например, включение визуального усечения строки в графическом экземпляре Emacs, использование неграфического Emacs для автоматического выполнения этого действия, отключение функций Bidi и т. Д.) И предварительная обработка содержимого файла, которое вы выполняете ». читаем дальше. Менее очевидным является автоматическая пост-обработка файлов, будь то путем обрезания их строк или добавления текстовых свойств, которые делают строки более короткими, чем они есть на самом деле. Чтобы превратить это в более интересный ответ, я представлю довольно некрасивый хак с предыдущей опцией, которая будет работать только для
comint
-приобретенных режимов:Это определяет
my-comint-shorten-long-lines
функцию, которая принимает строку, возможно состоящую из множества строк, и использует мощь регулярных выражений, чтобы заменить любую строку в ней длиной 80 символов или более сокращенной версией, которая отображает оригинальный текст при наведении на него курсора. При использовании в качестве хукаcomint-preoutput-filter-functions
он отфильтрует весьcomint
вывод перед его отображением.Тем не менее, это исполнение хака имеет довольно серьезную слабость. В режимах, в которых происходит базовая фонификация (например,
M-x ielm
), она удачно обрежет строки, являющиеся частью строки, и таким образом будет озвучивать все до следующей кавычки в виде строки! Это не то, что мы хотим, и может быть исправлено с помощью немного большего мастерства регулярных выражений (но, вероятно, будет нарушено внутри REPL для такого языка, как Python). Пока мы на этом, давайте выделим сокращенный вывод:Это немного лучше, но все еще безобразно. Помешать выводу чего-то вроде
find /
inM-x shell
не очень привлекательно (в идеале хотелось бы отображать только не укороченную строку, а не весь вывод), обнаружение строк в лучшем случае элементарно, и усечение можно было бы лучше обозначить с помощью эллипсов, а не осмысления всего. Кроме того, даже не гарантируется, что входящий текст не превращается в пакеты. Все это кричит о выполнении шага обработки во временном буфере, но будет оставлено читателю как упражнение (или автору как потенциальное сообщение в блоге).источник
Как и в случае с Python, решение по адресу python-mode.el, https://launchpad.net/python-mode , заключается в подключении к процессу напрямую, а не через comint-mode.
Полагается
start-process
и обрабатывает-отправляет-строкуНапример, см. Функции
py--start-fast-process
иpy--fast-send-string-intern
источник