Come posso ottenere una struttura in modalità org in un secondo buffer come indice dinamico?


25

Quando modifico documenti di grandi dimensioni, vorrei vedere dove mi trovo vedendo il contorno (senza contenuto) in un buffer separato. Come quando leggi un file PDF, c'è un sommario sulla sinistra. (vedi sotto)

In modalità org è possibile espandere / comprimere il contorno. Ma è possibile avere un contorno statico a sinistra (o destra) in un buffer separato in modo che quando si fa clic sulle intestazioni, l'altro buffer si sposta in quella posizione?

Un po 'come questo, ma per la modalità org? inserisci qui la descrizione dell'immagine

[Edit]
L' clone-indirect-bufferè molto vicino a quello che voglio. Il pezzo mancante del puzzle è saltare nella stessa posizione quando si fa clic su un'intestazione / (o su qualsiasi punto in realtà).

Per questo ho provato a scrivere del codice: passare ad altro buffer clonato nello stesso punto? (sincronizzazione della posizione dei buffer indiretti) (modalità org)

Ma non funziona se il contenuto viene compresso. Se ciò può essere fatto funzionare, allora il clone-inderect-buffer è una soluzione completa a questo.

[Soluzione Edit2]
Il codice nel link sopra e nella risposta sotto combinano niceley per risolvere il salto avanti e indietro.

;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
Forse prova C-c C-x b, o org-tree-to-indirect-buffer.
Samuel Flint,

@SWFlint Dopo un breve test, sembra che faccia qualcosa di diverso da ciò che l'OP vuole: copia l'attuale sottostruttura in un buffer indiretto. Ciò di cui avremmo bisogno sarebbe una org-sparse-tree-to-indirect-bufferfunzione, ad esempio, ma non sembra esistere.
T. Verron,

Dopo aver guardato un po 'oltre, prova qualcosa sulla falsariga dei riquadri organizzativi
Samuel Flint,

Penso che valga la pena menzionare anche la lista di imenu . Manca alcuni dei requisiti ma si rivolge ad altri.
incandescentman,

org-tree-to-indir-buffer è fantastico.
ninrod

Risposte:


9

Vengono in mente alcune opzioni. I primi due sono speedbar, che presumibilmente gioca bene con org-mode, e minimap, sebbene non li abbia usati, non posso garantirli personalmente.

Quale potrebbe essere l'opzione più semplice (e anche la più flessibile), sarebbe utilizzare un buffer indiretto .

In pratica, andresti nel orgbuffer per il quale desideri uno schema, premi M-x clone-indirect-buffer(usa C-u M-x clone-indirect-bufferse vuoi controllare come viene chiamato il clone), e poi boom, c'è un'altra copia del buffer che puoi usare. Metti quel clone in una finestra o cornice fianco a fianco con il buffer originale e, nel clone, regola il contorno secondo i tuoi gusti.

Non ti dà la funzionalità "fai clic sull'intestazione nella struttura" che hai citato, ma ti dà lo spirito della barra laterale.

Modifica: in risposta al tuo commento, ecco un semplice comando che, quando invocato dal clone del buffer , passerà al buffer di base e sposterà il punto in cui si trovava il cursore nel clone del buffer:

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

Ho provato speedbar / Sr-Speedbar. È molto bello ma mostra solo i primi 2 livelli. Ho chiesto se è possibile avere più livelli qui: emacs.stackexchange.com/questions/9533/… Il buffer indiretto è una buona opzione. Mi chiedo se sia possibile spostare in qualche modo il cursore nell'altro buffer nella stessa posizione del buffer clonato.
Leo Ufimtsev

Ho provato a scrivere codice che salti nella stessa posizione nell'altro buffer, ma funziona solo se tutto è espanso. Se può essere fatto funzionare in modo che si espanda automaticamente, il buffer clone è una soluzione perfetta. Post: emacs.stackexchange.com/questions/9536/…
Leo Ufimtsev

Grazie per lo snippet di codice sopra. Molto apprezzato ^ _ ^.
Leo Ufimtsev,

16

Che ne dici di: M-x occur RET ^*+ RET(nota che c'è uno spazio alla fine della regexp).


Non so perché qualcuno abbia annullato il voto a questa risposta, penso che questa sia in realtà una soluzione priva di problemi piuttosto carina. L'unica stranezza è che non ti segue in giro. Vale a dire che non è ovvio nel buffer occorrente in cui ci si trova (evidenziare l'intestazione corrente per esempio) e non scorre per documenti lunghi. Ma per piccoli documenti funziona.
Leo Ufimtsev,

Mi piace questa soluzione semplice e integrata. Se è necessario evidenziare, utilizzare helm-si verifica invece di verificarsi. Un ulteriore vantaggio è quello di essere in grado di utilizzare una sola navigazione per più buffer di file organizzativi utilizzando la funzione multiplo. Infine, con la modifica di occorrenza, è possibile modificare entrambe le viste, la vista struttura e la vista espansa. In ogni caso, sto votando a favore.
Utente Emacs

Valorizzeremo questo perché è fantastico, semplice ed efficiente
Gambo

Cosi 'semplice. Così intelligente. Così hacker. Così impressionante.
dangom

7

Dopo aver letto la risposta di Dan e la tua soluzione basata su di essa, ho messo insieme questo. Apre un nuovo clone stretto e di sola lettura a sinistra del buffer corrente e si lega <mouse-1>e RETlocalmente nel clone per saltare a quella posizione nel buffer di 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)))))

Funzionerà con outline-modee outline-minor-mode, così come con le modalità che si basano su di essi, come org-mode. Ho trovato alcune informazioni su come ottenere le mappe delle chiavi locali, ma non so come scegliere quale copiare. C'è anche questa pagina che ha una funzione per creare automaticamente modalità secondarie specifiche del buffer per impostare le chiavi locali del buffer, ma sembra fuori portata per questo problema.


1
Grazie per aver condiviso questo. Usando outline-mode-mapinvece di org-mode-mapsono riuscito a farlo funzionare AUCTeXcon outline-minor-mode, il che è bello.
Oleg Domanov,

A proposito, la outline-modefunzione di '' hide-bodynasconde tutto tranne i titoli.
Oleg Domanov,

@OlegDomanov Grazie per queste informazioni! Ho migliorato il codice per utilizzare outline-mode-mape hide-body, e alcuni altri miglioramenti minori.
Blujay,

2

Infine, questo è stato implementato nel pacchetto org-sidebar:

demo org-sidebar-tree


1
Hoooray! Ho una configurazione shakey che a volte smette di funzionare, è assolutamente BRILLANTE se è un pacchetto ora!
Prosegue l'

0

due suggerimenti di affitto basso (cosa faccio) da un non programmatore a cui piace usare aquamacs per l'editor di testo:

  1. alternare avanti e indietro con i comandi nel buffer:

STARTUP: indent (per mostrare più facilmente il contorno del tipo a cascata)

questo è per la visualizzazione basata su tab del buffer

e

+ OPZIONI: H: N, dove N = = il numero di livelli che desideri visualizzare nell'esportazione html, che è il suggerimento n. 2

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

  1. esporta come html (CC CE hh) per vedere il sommario. non riesco a trovare nessuno in grado di ottenere facilmente il rientro del testo di html o di testo (CC CE ta)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.