Как добиться эффекта сворачивания кода в Emacs?
каков наилучший способ достичь чего-то вроде сворачивания кода или типа езды на велосипеде, который использует org-mode. Каким было бы лучшее решение в elisp для создания такого типа поведения?
изменить: Простите, я не совсем ясно выразился. Я хочу запрограммировать что-то в elisp, что делает вещи, очень похожие на сворачивание кода, или на самом деле больше всего похоже на org-mode с иерархией, которая может быть расширена. Я задаюсь вопросом, как лучше всего достичь этого аффекта. Я думаю, я слышал, что оверлеи emacs хороши решение, но я не знаю.
Что касается складывания, я просто использую встроенный set-selective-display
ИЗМЕНИТЬ НОМЕР 2:
Спасибо за ответы, но я думаю, что я задаю неправильный вопрос, поэтому позвольте мне попытаться быть более ясным о том, что я пытаюсь сделать. Я хотел бы создать следующее
когда вы ставите свою точку на функцию и вызываете эту функцию elisp, она помещает определение функции из любого места (я думаю просто использовать find-tag для этого) и разверните его в текущем буфере. Идея в том, что если вам нужно перейти в другой буфер, чтобы прочитать определение функции, я чувствую, что его контекст переключается на другой файл. Поэтому я хотел бы, чтобы он вел себя как сворачивание кода, только он втягивает внешний код из буфера. Это создает некоторые проблемы, так как он не может вставить код в буфер или если кто-то его сохранит, он сохранит вытащенный код. Поэтому мне интересно, есть ли способ создать область внутри буфера, которая также не является частью буфера. Думаю, в этом есть смысл.
12 ответов
сворачивание обычно не требуется с emacs, поскольку у него есть инструменты, которые явно реализуют действия, которые люди делают вручную при сворачивании кода.
большинство людей имеют хороший успех с простым инкрементным поиском. "Фу" где-то упоминалось? Тип C-sfoo
, найдите определение, нажмите enter, прочитайте его, а затем нажмите C-x C-x вернуться туда, где вы были. Простой и очень полезный.
поддержка большинства режимов imenu. M-ximenu
позволит вам перейти к определению функции (и т. д.) по имени. Вы также можете привязать его к щелчку мыши, чтобы получить меню функций (или добавить его в меню; более подробную информацию см. На странице Info). Он предоставляет данные для which-function-mode, которые позволят вам увидеть, какую функцию вы сейчас находитесь внутри в modeline. (Но почему ваши функции так длинны?)
появилась панель быстрого доступа, который отображает imenu информация (и другие вещи) графически.
Если вы хотите получить обзор своего файла, попробуйте M-xoccur
". Учитывая регулярное выражение, он создаст новый буфер с каждым совпадением в текущем буфере. Вы можете найти "(defun", чтобы получить обзор функций, реализуемых текущим файлом. Нажатие на результат переместит вас на эту позицию в файле.
так или иначе, подумайте о том, чего вы действительно хотите достичь, и Emacs, вероятно, реализует это. Не сражайтесь с несовершенными инструментами, которые заставляют вас постоянно складывать и разворачивать вещи.
Скрыть-показать режим (hs-minor-mode
) с привязкой клавиш по умолчанию C-c @ C-M-h
для запуска складывания (hs-hide-all
)
еще один способ освежевать кота:
как это происходит, вам не нужен пакет или дополнительная конфигурация для что. Просто зайдите в любой исходный файл, типа
M-1 C-x $ и происходит волшебство!
как обычно, это белая магия: C-x $ вернет ваш код.
мы можем использовать справочную систему Emacs, чтобы узнать, что происходит: C-h k C-x $ говорит нам, что вышеуказанная комбинация клавиш вызова set-selective-display, функцию, которая принимает один числовой аргумент (префикс M-1 передает 1 Как значение этого аргумента) и, неудивительно, что устанавливает переменную selective-display в значение этот аргумент.
просто для полноты: M-3 C-x $ покажет более глубокий вложенный код и так далее.
FWIW я сделал крошечный помощник сегодня на основе smth. найдено здесь так что F5 переключает сворачивание кода на основе текущей позиции курсора:
(global-set-key (kbd "<f5>") 'set-selective-display-dlw)
(defun set-selective-display-dlw (&optional level)
"Fold text indented same of more than the cursor.
If level is set, set the indent level to LEVEL.
If 'selective-display' is already set to LEVEL, clicking
F5 again will unset 'selective-display' by setting it to 0."
(interactive "P")
(if (eq selective-display (1+ (current-column)))
(set-selective-display 0)
(set-selective-display (or level (1+ (current-column))))))
Я использую режим контура minor, чтобы сложить свой код python. Вместо того, чтобы размещать {{{ и }}} как в режиме сворачивания, он использует, где определен блок.
http://www.gnu.org/software/emacs/manual/html_node/emacs/Outline-Mode.html http://www.emacswiki.org/emacs/OutlineMinorMode
Я уверен, что он поставляется с emacs. Затем я добавляю это к своему .в Emacs
;;======= Code folding =======
(add-hook 'python-mode-hook 'my-python-outline-hook)
; this gets called by outline to deteremine the level. Just use the length of the whitespace
(defun py-outline-level ()
(let (buffer-invisibility-spec)
(save-excursion
(skip-chars-forward " ")
(current-column))))
; this get called after python mode is enabled
(defun my-python-outline-hook ()
; outline uses this regexp to find headers. I match lines with no indent and indented "class"
; and "def" lines.
(setq outline-regexp "[^ \t]\|[ \t]*\(def\|class\) ")
; enable our level computation
(setq outline-level 'py-outline-level)
; do not use their \C-c@ prefix, too hard to type. Note this overides some bindings.
(setq outline-minor-mode-prefix "\C-t")
; turn on outline mode
(outline-minor-mode t)
; initially hide all but the headers
;(hide-body)
; make paren matches visible
(show-paren-mode 1)
)
вы также можете получить сворачивание кода с помощью CEDET со следующим кодом в файле init:
(global-semantic-folding-mode t)
после оценки этого кода маленький треугольник появится в области fringle, поэтому вы сможете складывать и разворачивать код, используя его. Этот метод более точен, так как он использует синтаксическую информацию, извлеченную из исходного кода
HS-minor-mode работает красиво.
Он работает еще более красиво, когда в паре с fold-dwim (сделайте то, что я имею в виду). Затем есть fold-dwim-org, который обеспечивает org-mode как привязки ключей для сворачивания кода! Оба могут быть установлены через мармелад (и я думаю, elpa).
vimish-fold
также славное и легкое решение.
https://github.com/mrkkrp/vimish-fold.
на главной странице:
это пакет для выполнения складывания текста, как в Vim. Он имеет следующие особенности:
- складывание активных областей;
- хорошая визуальная обратная связь: очевидно, какая часть текста сложена;
- сохраняемость по умолчанию: при закрытии файла складки не исчезай;
- persistence scales ну, вы можете работать на сотнях файлов с большим количеством складок без побочных эффектов;
- он не ломает отступ или что-то;
- складки могут быть переключены из сложенного состояния в развернутое и обратно очень легко;
- быстрая навигация между существующими складок;
- вы можете использовать мышь, чтобы развернуть складки (хорошо для начинающих, а не только для них);
- для любителей avy пакет: вы можете использовать патчи чтобы сложить текст с минимальным количеством клавиш!
на use-package
Я устанавливаю и активирую его, используя этот фрагмент в моей конфигурации:
(use-package vimish-fold
:ensure t
:config (vimish-fold-global-mode t))
emacs приходит с HS-minor-mode который fascilitates складчатость кода между сбалансированными выражениями http://www.emacswiki.org/emacs/HideShow
Я считаю, что ваше сравнение вашего" проекта " со складыванием не совсем хорошо, потому что складывание-это изменение внешнего вида при сохранении содержимого буфера нетронутым (текст). Ваш проект будет включать показ дополнительного текста, сохраняя содержимое буфера нетронутым, AFAIU. Так. это не реализуемо как композиция вставки и складывания текста (тогда содержимое буфера будет изменено).
но, возможно, это действительно возможно с тем же механизмом, что и складывание покончено с ... "наложениями"... Рассмотрим "перед строкой" и "после строки" свойства оверлея; возможно, вы могли бы поместить свои определения функций в эти строки, принадлежащие наложению нулевой длины в точке. Посмотреть контур-флаг-регион функция, чтобы увидеть, как наложения используются в режиме контура.
Если вы используете hs-minor-mode
, было бы неплохо также установить более удобный ярлык, например:
(eval-after-load 'hideshow
'(progn
(global-set-key (kbd "C-+") 'hs-toggle-hiding)))
С вдохновением от einSelbst это:
(advice-add 'set-selective-display :filter-args (lambda (args) (if (or (car args) selective-display) args (list (1+ (current-column))))) '((name . set-selective-display-from-cursor-column)))
вуаля, C-x $
внезапно стал полезным даже без каких-либо C-u
, ни M-4
бизнес.