¿Cómo puedo obtener un esquema del modo org en un segundo búfer como una tabla de contenido dinámica?


25

Cuando edito documentos grandes, me gustaría ver dónde estoy viendo el esquema (sin contenido) en un búfer separado. Al igual que cuando lee un archivo PDF, hay una tabla de contenido a la izquierda. (vea abajo)

En el modo org es posible expandir / contraer el contorno. Pero, ¿es posible tener un contorno estático a la izquierda (o derecha) en un búfer separado para que cuando haga clic en los encabezados, el otro búfer se mueva a esa posición?

¿Un poco así pero para el modo org? ingrese la descripción de la imagen aquí

[Editar]
El clone-indirect-bufferestá muy cerca de lo que quiero. La pieza que falta en el rompecabezas es saltar a la misma ubicación al hacer clic en un encabezado / (o en cualquier punto).

Para esto he intentado escribir un código: ¿ Mover a otro búfer clonado al mismo punto? (posición de sincronización de buffers indirectos) (modo org)

Pero no funciona si el contenido se contrae. Si se puede hacer que funcione, entonces el clon-inderect-buffer es una solución completa para esto.

[Solución Edit2]
El código en el enlace de arriba y en la respuesta a continuación combinan niceley para resolver el salto de un lado a otro.

;first call 'clone-indirect-buffer'. Then...

;This function works between buffer and it's clone.
(defun my/goto-same-spot-in-other-buffer () 
  "Go to the same location in the other buffer. Useful for when you have cloned indirect buffers"
  (interactive)
  (let ((my/goto-current-point (point)))
       (other-window 1)
       (goto-char my/goto-current-point)
       (when (invisible-p (point))
        (org-reveal)))
)

;This function is a clone-to-buffer jump only:
; It does find the other buffer first thou instead of just jumping to the other 
; window as does the function above.
(defun my/jump-to-point-and-show ()
  "Switch to a cloned buffer's base buffer and move point to the
cursor position in the clone."
  (interactive)
  (let ((buf (buffer-base-buffer)))
    (unless buf
      (error "You need to be in a cloned buffer!"))
    (let ((pos (point))
          (win (car (get-buffer-window-list buf))))
      (if win
          (select-window win)
        (other-window 1)
        (switch-to-buffer buf))
      (goto-char pos)
      (when (invisible-p (point))
        (show-branches)))))


(global-set-key (kbd "<s-mouse-1>") 'my/goto-same-spot-in-other-buffer)
(global-set-key (kbd "s-m") 'my/goto-same-spot-in-other-buffer)
(global-set-key (kbd "<C-s-mouse-1>") 'my/jump-to-point-and-show)
(global-set-key (kbd "C-s-m") 'my/jump-to-point-and-show)

2
Tal vez intente C-c C-x b, o org-tree-to-indirect-buffer.
Samuel Flint

@SWFlint Después de una breve prueba, parece que hace algo diferente de lo que quiere el OP: copia el subárbol actual en un búfer indirecto. Lo que necesitaríamos sería una org-sparse-tree-to-indirect-bufferfunción, por ejemplo, pero no parece existir.
T. Verron

Después de buscar un poco más, pruebe algo similar a los paneles de organización
Samuel Flint, del

Creo que también vale la pena mencionar imenu-list . Carece de algunos de los requisitos pero aborda otros.
incandescentman

org-tree-to-indirecto-buffer es impresionante.
ninrod

Respuestas:


9

Algunas opciones me vienen a la mente. Los dos primeros son speedbar, con los que supuestamente juega bien org-mode, y minimap, aunque no los he usado, no puedo responder por ellos personalmente.

Lo que podría ser la opción más simple (y también la más flexible) sería utilizar un buffer indirecto .

En la práctica, iría al orgbúfer para el que desea un esquema, presione M-x clone-indirect-buffer(use C-u M-x clone-indirect-buffersi desea controlar cómo se llama el clon), y luego boom, hay otra copia del búfer para que use. Coloque ese clon en una ventana o marco lado a lado con el búfer original y, en el clon, ajuste el contorno a su gusto.

No le brinda la funcionalidad de "hacer clic en el encabezado en el esquema" que mencionó, pero le da el espíritu de la barra lateral.

Editar: en respuesta a su comentario, aquí hay un comando simple que, cuando se invoca desde el clon del búfer , cambiará al búfer base y moverá el punto a donde estaba el cursor en el clon del búfer:

(defun jump-to-point-and-show ()
  "Switch to a cloned buffer's base buffer and move point to the
cursor position in the clone."
  (interactive)
  (let ((buf (buffer-base-buffer)))
    (unless buf
      (error "You need to be in a cloned buffer!"))
    (let ((pos (point))
          (win (car (get-buffer-window-list buf))))
      (if win
          (select-window win)
        (other-window 1)
        (switch-to-buffer buf))
      (goto-char pos)
      (when (invisible-p (point))
        (show-branches)))))

Probé speedbar / Sr-Speedbar. Es muy agradable pero solo muestra los primeros 2 niveles. Pregunté si es posible tener más niveles aquí: emacs.stackexchange.com/questions/9533/… El buffer indirecto es una buena opción. Me pregunto si es posible mover de alguna manera el cursor en el otro búfer a la misma posición que en el búfer clonado ...
Leo Ufimtsev

Traté de escribir código que saltaría a la misma ubicación en el otro búfer, pero solo funciona si todo se expande. Si se puede hacer que funcione para que se expanda automáticamente, entonces el clon-buffer es una solución perfecta. Publicación
Leo Ufimtsev

Gracias por el fragmento de código anterior. Muy apreciado ^ _ ^.
Leo Ufimtsev

16

Qué tal: M-x occur RET ^*+ RET(tenga en cuenta que hay un espacio al final de la expresión regular).


No sé por qué alguien rechazó esta respuesta, creo que en realidad es una solución bastante sencilla y sin complicaciones. El único inconveniente es que no te sigue. Es decir, no es obvio en el búfer donde se encuentra (resalte el encabezado actual, por ejemplo) y no se desplaza por documentos largos y largos. Pero para documentos pequeños funciona.
Leo Ufimtsev

Me gusta esta solución simple e integrada. Si se necesita resaltar, use helm-ocurren en lugar de ocurrir. Un beneficio adicional es poder usar una única navegación para múltiples buffers de archivos de organización mediante el uso de múltiples ocurrencias. Por último, con produce-edit, se pueden editar ambas vistas, la vista de esquema y la vista expandida. En cualquier caso, estoy votando esto.
Usuario de Emacs el

Voy a votar esto porque es increíble, simple y eficiente
Gambo

Tan sencillo. Tan inteligente. Tan hack Tan genial.
Dangom 01 de

7

Después de leer la respuesta de Dan y su solución basada en ella, armé esto. Abre un clon nuevo, estrecho y de solo lectura a la izquierda del búfer actual, y se une <mouse-1>y RETlocalmente en el clon para saltar a esa posición en el búfer base.

(defun my/open-tree-view ()
  "Open a clone of the current buffer to the left, resize it to 30 columns, and bind <mouse-1> to jump to the same position in the base buffer."
  (interactive)
  (let ((new-buffer-name (concat "<tree>" (buffer-name))))
    ;; Create tree buffer
    (split-window-right 30)
    (if (get-buffer new-buffer-name)
        (switch-to-buffer new-buffer-name)  ; Use existing tree buffer
      ;; Make new tree buffer
      (progn  (clone-indirect-buffer new-buffer-name nil t)
              (switch-to-buffer new-buffer-name)
              (read-only-mode)
              (hide-body)
              (toggle-truncate-lines)

              ;; Do this twice in case the point is in a hidden line
              (dotimes (_ 2 (forward-line 0)))

              ;; Map keys
              (use-local-map (copy-keymap outline-mode-map))
              (local-set-key (kbd "q") 'delete-window)
              (mapc (lambda (key) (local-set-key (kbd key) 'my/jump-to-point-and-show))
                    '("<mouse-1>" "RET"))))))

(defun my/jump-to-point-and-show ()
  "Switch to a cloned buffer's base buffer and move point to the cursor position in the clone."
  (interactive)
  (let ((buf (buffer-base-buffer)))
    (unless buf
      (error "You need to be in a cloned buffer!"))
    (let ((pos (point))
          (win (car (get-buffer-window-list buf))))
      (if win
          (select-window win)
        (other-window 1)
        (switch-to-buffer buf))
      (goto-char pos)
      (when (invisible-p (point))
        (show-branches)))))

Esto funcionará con outline-modey outline-minor-mode, así como con los modos que se basan en ellos, como org-mode. Encontré información sobre cómo obtener los mapas de teclas locales, pero no sé cómo elegir cuál copiar. También existe esta página que tiene una función para crear automáticamente modos menores específicos del búfer para configurar las claves locales del búfer, pero eso parece estar fuera del alcance de este problema.


1
Gracias por compartir esto. Al usarlo en outline-mode-maplugar de hacerlo org-mode-map, logré hacerlo funcionar AUCTeXcon outline-minor-mode, lo cual es bueno.
Oleg Domanov

Por cierto, la outline-modefunción de 's hide-bodyoculta todo excepto los titulares.
Oleg Domanov

@OlegDomanov ¡Gracias por esa información! Mejoré el código para usar el outline-mode-mapy hide-body, y algunas otras mejoras menores.
Blujay

2

Finalmente, esto se ha implementado en el paquete org-sidebar:

demo de org-sidebar-tree


1
Hoooray! Tengo una configuración shakey que a veces simplemente deja de funcionar, ¡es absolutamente BRILLANTE si es un paquete ahora!
Thriveth

0

dos sugerencias de alquiler bajo (lo que hago) de un no programador al que le gusta usar aquamacs para editor de texto:

  1. alternar hacia adelante y hacia atrás con comandos en el búfer:

INICIO: sangría (para mostrar el contorno del tipo de cascada más fácil de ver como un todo)

Esto es para la visualización del búfer por pestañas

y

+ OPCIONES: H: N, donde N = = el número de niveles que desea ver en la exportación html, que es la sugerencia # 2

ver: https://emacsclub.github.io/html/org_tutorial.html

  1. exportar como html (CC CE hh) para ver TOC. no puedo encontrar a nadie que pueda obtener fácilmente la salida de texto de html o texto (CC CE ta)

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.