Como posso obter um esboço do modo organizacional em um segundo buffer como um índice dinâmico?

25

Quando edito documentos grandes, gostaria de ver onde estou vendo o esboço (sem conteúdo) em um buffer separado. Como quando você lê um arquivo PDF, há um sumário à esquerda. (ver abaixo)

No modo organizacional, é possível expandir / recolher o contorno. Mas é possível ter um contorno estático à esquerda (ou à direita) em um buffer separado, para que, quando você clicar nos títulos, o outro buffer se mova para essa posição?

Tipo assim, mas para o modo org? insira a descrição da imagem aqui

[Editar]
O clone-indirect-bufferestá muito perto do que eu quero. A peça que falta no quebra-cabeça é pular para o mesmo local ao clicar em um cabeçalho / (ou em qualquer outro ponto).

Por isso, tentei escrever algum código: Mover para outro buffer clonado no mesmo ponto? (posição de sincronização de buffers indiretos) (modo organizacional)

Mas não funciona se o conteúdo for recolhido. Se isso puder funcionar, o buffer de clonagem indereta é uma solução completa para isso.

[Edit2 Solution]
O código no link acima e na resposta abaixo combina niceley para resolver o salto para frente e para trás.

;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)
Leo Ufimtsev
fonte
2
Talvez tente C-c C-x b, ou org-tree-to-indirect-buffer.
Samuel Flint
@SWFlint Após um breve teste, parece que ele faz algo diferente do que o OP deseja: copia a subárvore atual para um buffer indireto. O que precisaríamos seria de uma org-sparse-tree-to-indirect-bufferfunção, por exemplo, mas parece não existir.
T. Verron
Depois de olhar um pouco mais, tentar algo ao longo das linhas de org-panes
Samuel Flint
Eu acho que também vale a pena mencionar a lista imenu . Falta alguns dos requisitos, mas aborda outros.
incandescentman
org-árvore-para-buffer-indireto é impressionante.
Ninrod 02/04

Respostas:

9

Algumas opções vêm à mente. Os dois primeiros são speedbar, que supostamente funcionam bem org-modee minimap, embora eu não os tenha usado, não posso atestá-los pessoalmente.

O que poderia ser a opção mais simples (e também a mais flexível) seria usar um buffer indireto .

Na prática, você iria para o orgbuffer para o qual deseja um esboço, pressionaria M-x clone-indirect-buffer(use C-u M-x clone-indirect-bufferse quiser controlar o que o clone é chamado) e, em seguida, boom, há outra cópia do buffer para você usar. Coloque esse clone em uma janela ou moldura lado a lado com o buffer original e, no clone, ajuste o contorno ao seu gosto.

Ele não fornece a funcionalidade "clique no cabeçalho no esboço" que você mencionou, mas fornece o espírito da barra lateral.

Edit: em resposta ao seu comentário, aqui está um comando simples que, quando chamado do clone do buffer , mudará para o buffer base e moverá o ponto para onde o cursor estava no clone do 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)))))
Dan
fonte
Eu experimentei o speedbar / Sr-Speedbar. É muito bom, mas mostra apenas os 2 primeiros níveis. Perguntei se é possível ter mais níveis aqui: emacs.stackexchange.com/questions/9533/… O buffer indireto é uma boa opção. Gostaria de saber se é possível mover o cursor de alguma forma no outro tampão para a mesma posição que no tampão clonado ..
Leo Ufimtsev
Tentei escrever um código que salta para o mesmo local no outro buffer, mas só funciona se tudo for expandido. Se puder ser feito para que ele se expanda automaticamente, o buffer de clone é uma solução perfeita. Mensagem: emacs.stackexchange.com/questions/9536/…
Leo Ufimtsev
Obrigado pelo trecho de código acima. Muito apreciado ^ _ ^.
Leo Ufimtsev 24/02
16

Que tal: M-x occur RET ^*+ RET(observe que há um espaço no final do regexp).

Minha outra sopa é um Borscht
fonte
Eu não sei por que alguém votou negativamente nesta resposta, acho que na verdade é uma solução bastante simples e sem complicações. O único truque é que ele não segue você por aí. Ou seja, não é óbvio no buffer de ocorrência onde você está (destaque o título atual, por exemplo) e ele não rola para documentos longos. Mas, para pequenos documentos, funciona.
Leo Ufimtsev 25/02
Gosto desta solução simples e integrada. Se precisar realçar, use helm-ocorrem em vez de ocorrer. Um benefício adicional é poder usar uma única navegação para vários buffers de arquivo organizacional usando a ocorrência múltipla. Por fim, com a edição de ocorrência, é possível editar as duas vistas, a vista de estrutura de tópicos e a vista expandida. De qualquer forma, estou votando positivamente nisso.
Emacs usuário
Indo para upvote isso porque seu impressionante, simples e eficiente
Gambo
Tão simples. Tão inteligente. Tão hackish. Tão maravilhoso.
Dangom 01/08/19
7

Depois de ler a resposta de Dan e sua solução com base nela, eu reuni isso. Ele abre um novo clone estreito, somente leitura, à esquerda do buffer atual e liga <mouse-1>e RETlocalmente no clone para pular para essa posição no buffer 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)))))

Isso funcionará com outline-modee outline-minor-mode, assim como modos baseados neles, como org-mode. Encontrei algumas informações sobre como obter os mapas de chaves locais, mas não sei como escolher qual deles copiar. Há também esta página que tem uma função para criar automaticamente modos menores específicos de buffer para definir chaves locais de buffer, mas isso parece fora do escopo para esse problema.

Blujay
fonte
11
Obrigado por compartilhar isso. Usando outline-mode-mapem vez de org-mode-mapeu consegui fazê-lo trabalhar para AUCTeXcom outline-minor-mode, o que é bom.
Oleg Domanov 03/11/2015
A propósito, a outline-modefunção da hide-bodyesconde tudo, exceto as manchetes.
precisa saber é o seguinte
@OlegDomanov Obrigado por essa informação! Aprimorei o código para usar o outline-mode-mape hide-body, e algumas outras pequenas melhorias.
blujay
2

Por fim, isso foi implementado no pacote org-sidebar:

demonstração da org-sidebar-tree

Blujay
fonte
11
Hoooray! Eu tenho uma configuração de shakey que às vezes para de funcionar, é absolutamente BRILHANTE se for um pacote agora!
Thriveth
0

duas sugestões de aluguel baixo (o que eu faço) de um não programador que gosta de usar aquamacs no editor de texto:

  1. alternar para frente e para trás com os comandos no buffer:

INÍCIO: recuo (para mostrar o contorno do tipo cascata mais fácil de ver como um todo)

isto é para visualização de buffer orientada por tabulação

e

+ OPÇÕES: H: N, onde N = = o número de níveis que você deseja ver na exportação de html, que é a sugestão 2

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

  1. exportar como html (CC CE hh) para ver o sumário. Não consigo encontrar ninguém que possa facilmente obter a saída de texto de html ou texto (CC CE ta) para recuar
Richrat
fonte
0

Eu precisava de algo semelhante, então montei o outline-tocmodo . Deve funcionar para documentos no modo organizacional.

Abingham
fonte