¿Cómo lograr efectos de plegado de código en Emacs?


123

¿Cuál es la mejor manera de lograr algo como el plegado de código o el tipo de ciclo que usa el modo org? ¿Cuál sería la mejor solución en elisp para crear este tipo de comportamiento?

EDITAR: Lo siento, no estaba claro. Quiero programar algo en elisp que haga cosas muy similares al plegado de código, o en realidad más como org-mode con la jerarquía que se puede expandir. Me pregunto cuál es la mejor manera de lograr este efecto. Creo que he oído que las superposiciones de emacs son una buena solución, pero no lo sé.

En cuanto al plegado, solo uso la pantalla selectiva de conjunto incorporada

EDITAR NÚMERO 2:

Gracias por las respuestas, pero creo que estoy haciendo la pregunta incorrecta, así que permítanme tratar de ser más claro sobre lo que estoy tratando de hacer. Me gustaría crear lo siguiente

Cuando pones tu punto en una función y llamas a esta función elisp, pondrá la definición de la función desde donde esté (estoy pensando en usar la etiqueta de búsqueda para esto) y la desplegará en el búfer actual. La idea es que si tiene que saltar a un búfer diferente para leer la definición de la función, siento que es un cambio de contexto a otro archivo. Así que me gustaría que se comportara como un plegado de código, solo que extrae código externo del búfer. Esto presenta algunos problemas, ya que no se puede pegar el código en el búfer o si alguien lo guarda, se guardará el código extraído. Entonces, me pregunto si hay una forma de crear un área dentro de un búfer que tampoco es parte del búfer. Creo que eso tiene sentido.


¿Está buscando algo que cuando lo llame con un punto en una función CALL salte a la definición de la función? algo así como obtener ayuda sobre una función elisp le permitirá saltar al código elisp? No creo que puedas hacer esto sin algún concepto de "El proyecto". Por ejemplo, ¿cómo sabrías a qué función de "intercambio" quieres saltar?
Brian Postow

1
Consulte también: stackoverflow.com/questions/382781/… donde la visualización selectiva se modifica un poco para obtener algunos efectos de plegado.
Michael Paulukonis

Te recomiendo que elimines el tuyo EDIT NB 2y le hagas una nueva pregunta.
Stefan

Respuestas:


151

El plegado es generalmente innecesario con emacs, ya que tiene herramientas que implementan explícitamente las acciones que la gente realiza manualmente al plegar código.

La mayoría de las personas tienen un buen éxito con búsquedas incrementales simples. ¿Ves "foo" mencionado en alguna parte? Escriba C-sfoo, busque la definición, presione Intro, léalo y luego presione C-x C-xpara volver a donde estaba. Sencillo y muy útil.

La mayoría de los modos admiten imenu . M-ximenule permitirá saltar a una definición de función (etc.) por su nombre. También puede vincularlo a un clic del mouse para obtener un menú de funciones (o agregarlo a la barra de menú; consulte la página Información para obtener más detalles). Proporciona datos para qué modo de función, lo que le permitirá ver en qué función se encuentra actualmente en la línea de modo. (Sin embargo, ¿por qué sus funciones son tan largas?)

También hay una barra de velocidad , que muestra la información del imenu (y otras cosas) gráficamente.

Si desea obtener una descripción general de su archivo, intente M-xoccur". Dada una expresión regular, creará un nuevo búfer con cada coincidencia en el búfer actual. Puede buscar" (defun "para obtener una descripción general de las funciones del archivo actual Implementos Al hacer clic en el resultado, se moverá a esa posición en el archivo.

De todos modos, piense en lo que realmente quiere lograr, y probablemente Emacs lo implemente. No luches con herramientas imperfectas que te hacen doblar y desplegar cosas constantemente.


13
Vim también proporciona todas estas características de una forma u otra, pero todavía encuentro invaluable su facilidad de plegado de código.
intuido el

115
Voté en contra de la primera oración ("El plegado es generalmente innecesario con emacs, ya que ..."). Utilizo el plegado simple (basado en el nivel de sangría) constantemente para escanear la estructura del código desconocido.
Simon Michael

4
Ms o es el atajo para Mx ocurre
Joshua Olson

3
Voté porque hay muchos atajos útiles en la respuesta, pero también voté positivamente en el comentario de @SimonMichael porque ¡doblar / desplegar aún podría ser útil a veces!
Adrien Coquio

56
La respuesta fue bien pensada y muy informativa. Sin embargo, el OP preguntó cómo hacer el plegado de código. El OP no preguntó cuál era la forma favorita de todos de evitar el plegado de código. Votado en contra.
wkschwartz

104

modo ocultar-mostrar ( hs-minor-mode) con combinación C-c @ C-M-hde teclas predeterminada para activar el plegado ( hs-hide-all)


12
Esto funciona bien. Y con el mal modo, esto es provocado por los comandos normales vim: zR, zM, zo, zc.
Justin M. Keyes

39

Otra forma de despellejar al gato:

Da la casualidad de que no necesita ningún paquete o configuración adicional para eso. Simplemente vaya a cualquier archivo fuente, escriba

M-1 Cx $ ¡ y la magia sucede!

Como de costumbre, es magia blanca: Cx $ traerá su código de regreso.

Podemos usar el sistema de ayuda de Emacs para descubrir qué está sucediendo: Ch k Cx $ nos dice que la combinación de teclas anterior está llamando a set-selected-display , una función que toma un argumento numérico (el prefijo M-1 pasa 1 como valor de ese argumento) y, como era de esperar, establece la variable selectiva-display en el valor de ese argumento.

del blog de hechicería menor de emacs

Solo para completar: M-3 Cx $ mostraría un código anidado más profundo y así sucesivamente.

FWIW Hice un pequeño ayudante hoy basado en algo. encontrado aquí para que F5 alterne el plegado de código según la posición actual del cursor:

(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))))))

22

Utilizo el modo de esquema menor para plegar mi código de Python. En lugar de necesitar colocar {{{y}}} como en el modo de plegado, usa donde se define el bloque.

http://www.gnu.org/software/emacs/manual/html_node/emacs/Outline-Mode.html http://www.emacswiki.org/emacs/OutlineMinorMode

Estoy bastante seguro de que viene con emacs. Luego agrego esto a mi .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)
)

8
parece que outline-modeadmite Python listo para usar en emacs 24, sin necesidad de outline-levelfunciones personalizadas . Esto es todo lo que necesitaba agregar a mi user.el:(add-hook 'python-mode-hook 'outline-minor-mode)
scytale

1
oh, y definitivamente quieres anular outline-minor-mode-prefix- las combinaciones de teclas predeterminadas son horribles - yo uso(setq outline-minor-mode-prefix (kbd "C-;"))
scytale

13

También puede obtener el plegado de código utilizando CEDET con el siguiente código en el archivo de inicio:

(global-semantic-folding-mode t)

Después de la evaluación de este código, el triángulo pequeño aparecerá en el área de flecos, por lo que podrá plegar y desplegar el código usándolo. Este método es más preciso, ya que utiliza información sintáctica extraída del código fuente.


1
si se enfrenta a algún error, eche un vistazo a esta pregunta: stackoverflow.com/questions/15307113/…
AdrieanKhisbe

9

hs-minor-mode funciona a la perfección.

Funciona aún mejor cuando se combina con fold-dwim (haz lo que quiero decir). Luego está fold-dwim-org, que proporciona combinaciones de teclas similares al modo org para el plegado de código. Ambos se pueden instalar vía mermelada (y creo que elpa).



5

vimish-fold también es una solución agradable y fácil.

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

Desde la página de inicio:

Este es un paquete para realizar el plegado de texto como en Vim. Tiene las siguientes características:

  • plegamiento de regiones activas;
  • buena retroalimentación visual: es obvio qué parte del texto está plegada;
  • persistencia por defecto: cuando cierras el archivo tus pliegues no desaparecen;
  • la persistencia se escala bien, puede trabajar en cientos de archivos con muchos pliegues sin efectos adversos;
  • no rompe la hendidura o algo así;
  • los pliegues se pueden cambiar de estado plegado a desplegado y hacia atrás muy fácilmente;
  • navegación rápida entre pliegues existentes;
  • puede usar el mouse para desplegar los pliegues (bueno para principiantes y no solo para ellos);
  • para los fanáticos del paquete avy: puede usar avy para doblar texto con un número mínimo de pulsaciones de teclas.

Usando el excelente, use-packagelo instalo y lo activo usando este fragmento en mi configuración:

(use-package vimish-fold
  :ensure t
  :config (vimish-fold-global-mode t))

3

Me sorprende que nadie haya mencionado el estrechamiento-ensanchamiento. Es súper impresionante, también viene con emacs. Simplemente seleccione el código en el que desea enfocarse y presione C-x n n, para volver al modo de vista completa, simplemente hágalo C-x n w. Siempre prefiero usar la funcionalidad emacs incorporada que saturar mi espacio de usuario con otro paquete. Si emacs puede hacerlo con la funcionalidad incorporada, entonces lo preferiré a algún paquete de terceros, pero ese soy solo yo, no significa ni implica nada más además de que me gustan las cosas simples sobre las configuraciones largas y complejas.



2

Creo que su comparación de su "proyecto" con el plegado no es del todo buena, porque plegar consiste en cambiar la apariencia manteniendo intacto el contenido del búfer (el texto). Su proyecto implicaría mostrar texto adicional mientras se mantiene intacto el contenido del búfer, AFAIU. Entonces. no se puede implementar como una composición de inserción y plegado de texto (entonces, se cambiaría el contenido del búfer).

Pero quizás, de hecho es posible con el mismo mecanismo que el plegado con - "superposiciones" ... Considere las propiedades de superposición "antes de la cadena" y "después de la cadena" ; tal vez, podría poner sus definiciones de función en estas cadenas que pertenecen a una superposición de longitud cero en el punto. Mire la función outline-flag-region para ver cómo se usan las superposiciones en el modo de esquema.


2

Si lo usa hs-minor-mode, podría ser una buena idea establecer también un atajo más conveniente, por ejemplo:

(eval-after-load 'hideshow
 '(progn
   (global-set-key (kbd "C-+") 'hs-toggle-hiding)))

0

Con inspiración de Inspirado en la respuesta einSelbst :

(consejo-añadir 'set-selected-display
            : filter-args (lambda (argumentos)
                           (si (o (coche argumenta) pantalla selectiva)
                               argumentos
                             (lista (1+ (columna actual)))))
            '((nombre. conjunto-visualización-selectiva-desde-columna-cursor)))

Voila, C-x $de repente se convirtió útil incluso sin ningún tipo C-uni M-4de negocios.


0

Si está usando JavaScript y lo usa js2-mode.el, puede:

C-c C-f: alternar ocultar / mostrar todo

C-c C-e: ocultar elemento

C-c C-s: mostrar elemento

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.