Как добиться эффекта сворачивания кода в Emacs?

123

Как лучше всего добиться чего-то вроде сворачивания кода или типа цикличности, который использует организационный режим? Какое решение в elisp было бы лучшим для создания такого поведения?

РЕДАКТИРОВАТЬ: Мне жаль, что я не понял. Я хочу запрограммировать на elisp что-то, что очень похоже на сворачивание кода, или на самом деле больше похоже на org-mode с иерархией, которую можно расширять. Мне интересно, как лучше всего добиться этого эффекта. Я думаю, что слышал, что оверлеи emacs - хорошее решение, но я не знаю.

Что касается складывания, я просто использую встроенный набор-выборочный дисплей.

ИЗМЕНИТЬ НОМЕР 2:

Спасибо за ответы, но я думаю, что задаю неправильный вопрос, поэтому позвольте мне попытаться пояснить, что я пытаюсь сделать. Я хотел бы создать следующие

Когда вы помещаете свою точку в функцию и вызываете эту функцию elisp, она помещает определение функции из любого места (я думаю о том, чтобы просто использовать для этого find-tag) и разворачивать его в текущем буфере. Идея в том, что если вам нужно перейти в другой буфер, чтобы прочитать определение функции, я чувствую, что это переключение контекста на другой файл. Поэтому я хотел бы, чтобы он вел себя как сворачивание кода, только он извлекает код извне из буфера. Это создает некоторые проблемы, поскольку он не может фактически вставить код в буфер или, если кто-то его сохранит, он сохранит втянутый код. Поэтому мне интересно, есть ли способ создать область внутри буфера, которая также не является частью буфера. Думаю, в этом есть смысл.

Джекоб
источник
Вы ищете что-то, что, когда вы вызываете это с помощью точки в функции CALL, она переходит к определению функции? что-то вроде получения справки по функции elisp позволит вам перейти к коду elisp? Я не думаю, что вы можете сделать это без какой-либо концепции «проекта». Например, как вы узнаете, к какой функции «подкачки» вы хотите перейти?
Брайан Постоу,
1
См. Также: stackoverflow.com/questions/382781/… где выборочное отображение немного настроено для некоторых эффектов, подобных сворачиванию.
Майкл Паулюконис
Я рекомендую вам удалить свой EDIT NB 2и задать для него новый вопрос.
Стефан

Ответы:

151

В emacs сворачивание обычно не требуется, поскольку в нем есть инструменты, которые явно реализуют действия, которые люди делают вручную при сворачивании кода.

Большинство людей добиваются успеха с помощью простых пошаговых поисков. Видите где-то "foo"? Введите C-sfoo, найдите определение, нажмите ввод, прочтите его, а затем нажмите, C-x C-xчтобы вернуться туда, где вы были. Просто и очень полезно.

Большинство режимов поддерживают имя . M-ximenuпозволит вам перейти к определению функции (и т. д.) по имени. Вы также можете привязать его к щелчку мыши, чтобы получить меню функций (или добавить его в строку меню; см. Страницу «Информация» для более подробной информации). Он предоставляет данные для режима-функции, которые позволят вам увидеть, в какой функции вы сейчас находитесь в строке режима. (Но почему ваши функции такие длинные?)

Также есть панель быстрого доступа , которая отображает информацию об имени (и других вещах) графически.

Если вы хотите получить обзор вашего файла, попробуйте M-xoccur". Учитывая регулярное выражение, он создаст новый буфер с каждым совпадением в текущем буфере. Вы можете выполнить поиск" (defun ", чтобы получить обзор функций текущего файла Нажав на результат, вы переместитесь в эту позицию в файле.

Так или иначе, подумайте о том, чего вы действительно хотите достичь, и Emacs, вероятно, это реализует. Не сражайтесь с несовершенными инструментами, которые заставляют вас постоянно складывать и раскладывать вещи.

jrockway
источник
13
Vim также предоставляет все эти функции в той или иной форме, но я по-прежнему считаю его средство сворачивания кода бесценным.
интуитивно понятен
115
Я проголосовал против первого предложения («Сворачивание обычно не требуется с emacs, поскольку ...»). Я постоянно использую простое сворачивание (на основе уровня отступа), чтобы сканировать структуру незнакомого кода.
Саймон Майкл
4
Ms o - это ярлык для Mx.
Джошуа Олсон
3
Я проголосовал за многие полезные ярлыки в ответе, но также поддержал комментарий @SimonMichael, потому что иногда складывание / развертывание все еще может быть полезно!
Adrien Coquio,
56
Ответ был хорошо продуман и очень информативен. Однако OP спросил, как выполнить сворачивание кода. ОП не спрашивал, какой у всех любимый способ избежать сворачивания кода. Проголосовал против.
wkschwartz
104

hide-show mode ( hs-minor-mode) с привязкой клавиш C-c @ C-M-hпо умолчанию для запуска функции сворачивания ( hs-hide-all)

dmckee --- котенок экс-модератора
источник
12
Это хорошо работает. И со злым режимом, это вызвано нормальными командами VIM: zR, zM, zo, zc.
Джастин М. Киз
39

Еще один способ снять шкуру с кошки:

Как оказалось, для этого не требуется никаких пакетов или дополнительных настроек. Просто перейдите в любой исходный файл, введите

M-1 Cx $ и волшебство происходит!

Как обычно, это белая магия: Cx $ вернет ваш код.

Мы можем использовать справочную систему Emacs, чтобы узнать, что происходит: Ch k Cx $ сообщает нам, что указанная выше комбинация клавиш вызывает set-selected-display , функцию, которая принимает один числовой аргумент (префикс M-1 передает 1 как значение этого аргумента) и, что неудивительно, устанавливает переменную selection-display равной значению этого аргумента.

из второстепенного блога emacs wizardry

Для полноты: M-3 Cx $ покажет более глубокий вложенный код и так далее.

FWIW Сегодня я сделал крошечного помощника, основанного на чем-л. найдено здесь, так что 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))))))
einSelbst
источник
22

Я использую второстепенный режим структуры, чтобы свернуть свой код 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)
)
Nikwin
источник
8
похоже, outline-modeподдерживает python в emacs 24 из коробки - нет необходимости в пользовательских outline-levelфункциях. Это все, что мне нужно было добавить к моему user.el:(add-hook 'python-mode-hook 'outline-minor-mode)
scytale
1
о, и вы определенно хотите переопределить outline-minor-mode-prefix- комбинации клавиш по умолчанию ужасны - я использую(setq outline-minor-mode-prefix (kbd "C-;"))
scytale
13

Вы также можете получить сворачивание кода, используя CEDET со следующим кодом в файле инициализации:

(global-semantic-folding-mode t)

После оценки этого кода маленький треугольник появится в области окантовки, поэтому вы сможете сворачивать и разворачивать код, используя его. Этот метод более точен, поскольку использует синтаксическую информацию, извлеченную из исходного кода.

Алекс Отт
источник
1
если вы столкнулись с какой-либо ошибкой, взгляните на этот вопрос: stackoverflow.com/questions/15307113/…
AdrieanKhisbe
9

hs-minor-mode прекрасно работает.

Это работает еще лучше в сочетании с fold-dwim (делайте то, что я имею в виду). Затем есть fold-dwim-org, которая предоставляет org-mode, например привязки клавиш для сворачивания кода! Оба могут быть установлены через мармелад (и я думаю, что elpa).

Джонс
источник
5

vimish-fold также хорошее и простое решение.

https://github.com/mrkkrp/vimish-fold .

С домашней страницы:

Это пакет для свертывания текста, как в Vim. Он имеет следующие особенности:

  • сворачивание активных областей;
  • хорошая визуальная обратная связь: видно, какая часть текста свернута;
  • постоянство по умолчанию: при закрытии файла складки не исчезают;
  • устойчивость хорошо масштабируется, вы можете работать с сотнями файлов с большим количеством складок без каких-либо побочных эффектов;
  • он не нарушает отступов или чего-то еще;
  • складки можно легко переключать из сложенного состояния в разложенное и обратно;
  • быстрая навигация между существующими складками;
  • раскладывать складки можно мышкой (подойдет новичкам и не только);
  • для поклонников пакета avy: вы можете использовать avy для сворачивания текста с минимальным количеством нажатий клавиш!

Используя отличный, use-packageя устанавливаю и активирую его, используя этот фрагмент в моей конфигурации:

(use-package vimish-fold
  :ensure t
  :config (vimish-fold-global-mode t))
Horus
источник
3

Я удивлен, что никто не упомянул сужение-расширение. Это супер круто, он тоже идет в комплекте с emacs. Просто выберите код, на котором вы хотите сосредоточиться, и нажмите C-x n n, чтобы вернуться в полноэкранный режим, просто сделайте это C-x n w. Я всегда предпочитаю использовать встроенные функции emacs, чем загромождать свое пользовательское пространство другим пакетом. Если emacs может делать это со встроенными функциями, тогда я предпочитаю это каким-то сторонним пакетам, но это только я, не означает и не подразумевает чего-либо еще, кроме того, что мне нравятся простые вещи, а не сложные длинные конфигурации.

Кирк Уолла
источник
2

Я считаю, что ваше сравнение вашего «проекта» со сворачиванием не совсем удачно, потому что сворачивание - это изменение внешнего вида при сохранении неизменного содержимого буфера (текста). Ваш проект будет включать отображение дополнительного текста при сохранении неизменного содержимого буфера, AFAIU. Так. это нереализуемо как композиция вставки и сворачивания текста (тогда содержимое буфера будет изменено).

Но, возможно, это действительно возможно с тем же механизмом, что и сворачивание с помощью - «overlays» ... Рассмотрим свойства наложения «before-string» и «after-string» ; возможно, вы могли бы поместить определения ваших функций в эти строки, принадлежащие наложению нулевой длины в точке. Посмотрите на функцию outline-flag-region, чтобы увидеть, как наложения используются в режиме контура.

imz - Иван Захарящев
источник
2

Если вы используете hs-minor-mode, было бы неплохо также установить более удобный ярлык, например:

(eval-after-load 'hideshow
 '(progn
   (global-set-key (kbd "C-+") 'hs-toggle-hiding)))
quazgar
источник
0

Вдохновленный ответом einSelbst :

(совет-добавить 'выбор-выбор-отображение
            : filter-args (лямбда (аргументы)
                           (если (или (аргументы машины) выборочное отображение)
                               арг
                             (список (1+ (текущий столбец)))))
            '((имя. набор-выбор-отображение-из-курсора-столбца)))

Вуаля, C-x $вдруг стал полезным , даже без какого - либо C-uни M-4бизнеса.

DomQ
источник
0

Если вы используете JavaScript и используете его js2-mode.el, вы можете:

C-c C-f: переключить скрыть / показать все

C-c C-e: скрыть элемент

C-c C-s: показать элемент

roboli
источник