Como usar "o" para abrir do dired / ibuffer para outro quadro

8

Tenho duas janelas abertas e divididas verticalmente (quadro único):

A) contém meu trabalho
B) contém dired ou ibuffer.

Gostaria de poder navegar para um arquivo / buffer no painel B e pressionar "o" para abri-lo no painel A. Isso é possível? No momento, o emacs está criando um novo painel na parte inferior do painel A para abrir o arquivo.

editar: de acordo com a lista de leis do usuário, o comportamento descrito acima ocorrerá quando o quadro for grande. Parece ser esse o meu caso, porque agora que estou em casa (não em um monitor externo, quadro menor), o emacs está se comportando como desejo. A questão agora é: posso impedir que o emacs abra uma nova janela quando o quadro atual for grande?

Robert
fonte
1
Bem-vindo ao fórum beta do Emacs. Como parte do jargão / jargão do Emacs, usamos a palavra windowpara se referir a um quadrante de buffer dentro do mesmo frame. A frameé considerado todo o kitten-kaboodle, que pode ter muitas janelas dentro dele. O Emacs pode gerar vários quadros, com cada quadro contendo várias janelas.
lawlist
obrigado pelo esclarecimento! Sou usuário do emacs há muito tempo, mas nunca entendi completamente a terminologia.
Robert

Respostas:

6

Aqui estão quatro (4) exemplos de display-bufferfamílias de funções personalizadas que podem ser personalizadas de acordo com as necessidades específicas de um usuário - acima ; abaixo ; esquerda ; direita - e aqui estão quatro (4) interactivefunções para exibir o arquivo ou diretório da linha atual de um dired-modebuffer. Existem apenas três condições: (a) se já houver uma janela exibindo o buffer de destino, escolha-o; (b) se houver uma janela na direção desejada disponível, use-a; (c) o objetivo é criar uma nova janela na direção desejada se as outras condições não forem atendidas.

Uso:

M-x dired-display-above

M-x dired-display-below

M-x dired-display-left

M-x dired-display-right

Existem tantas combinações de teclas já embutidas dired-modee dired+que não ouso tentar criar minhas próprias. O usuário é livre para escolher seus próprios atalhos de teclado, que estão além do escopo deste exemplo limitado.

O usuário pode adicionar condições adicionais à display-bufferfamília de funções de amostra para lidar com mais situações - por exemplo, mais janelas do que apenas algumas.

(defun my-display-buffer-below (buffer alist)
"Doc-string."
  (let (
      (window
        (cond
          ((get-buffer-window buffer (selected-frame)))
          ((window-in-direction 'below))
          (t
            (split-window (selected-window) nil 'below)))))
    (window--display-buffer buffer window 'window alist display-buffer-mark-dedicated)
    window))

(defun my-display-buffer-above (buffer alist)
"Doc-string."
  (let (
      (window
        (cond
          ((get-buffer-window buffer (selected-frame)))
          ((window-in-direction 'above))
          (t
            (split-window (selected-window) nil 'above)))))
    (window--display-buffer buffer window 'window alist display-buffer-mark-dedicated)
    window))

(defun my-display-buffer-left (buffer alist)
"Doc-string."
  (let (
      (window
        (cond
          ((get-buffer-window buffer (selected-frame)))
          ((window-in-direction 'left))
          (t
            (split-window (selected-window) nil 'left)))))
    (window--display-buffer buffer window 'window alist display-buffer-mark-dedicated)
    window))

(defun my-display-buffer-right (buffer alist)
"Doc-string."
  (let (
      (window
        (cond
          ((get-buffer-window buffer (selected-frame)))
          ((window-in-direction 'right))
          (t
            (split-window (selected-window) nil 'right)))))
    (window--display-buffer buffer window 'window alist display-buffer-mark-dedicated)
    window))

(defun dired-display-above ()
"Doc-string."
(interactive)
  (let* (
      (file-or-dir (dired-get-file-for-visit))
      (buffer (find-file-noselect file-or-dir)))
    (my-display-buffer-above buffer nil)))

(defun dired-display-below ()
"Doc-string."
(interactive)
  (let* (
      (file-or-dir (dired-get-file-for-visit))
      (buffer (find-file-noselect file-or-dir)))
    (my-display-buffer-below buffer nil)))

(defun dired-display-left ()
"Doc-string."
(interactive)
  (let* (
      (file-or-dir (dired-get-file-for-visit))
      (buffer (find-file-noselect file-or-dir)))
    (my-display-buffer-left buffer nil)))

(defun dired-display-right ()
"Doc-string."
(interactive)
  (let* (
      (file-or-dir (dired-get-file-for-visit))
      (buffer (find-file-noselect file-or-dir)))
    (my-display-buffer-right buffer nil)))

EDIT: Aqui está uma implementação um pouco mais sofisticada / divertida do conceito acima, que dá ao usuário a capacidade de usá-lo de maneira não interativa ou interativa ; por exemplo, M-x dired-display-buffer- onde o usuário será solicitado a escolher um diretório, se não passar o mouse sobre um arquivo dired-mode, e escolher uma direção de exibição (esquerda, direita, acima, abaixo).

(defun my-display-buffer (buffer-or-name alist direction &optional size pixelwise)
"BUFFER:  The buffer that will be displayed.
ALIST:  See the doc-string of `display-buffer' for more information.
DIRECTION:  Must use one of these symbols:  'left 'right 'below 'above
SIZE:  See the doc-string for `split-window'.
PIXELWISE:  See the doc-string for `split-window'.
There are three possibilities:
-  (1) If a window on the frame already displays the target buffer,
then just reuse the same window.
-  (2) If there is already a window in the specified direction in relation
to the selected window, then display the target buffer in said window.
-  (3) If there is no window in the specified direction, then create one
in that direction and display the target buffer in said window."
  (let* ((buffer
           (if (bufferp buffer-or-name)
             buffer-or-name
             (get-buffer buffer-or-name)))
         (window
           (cond
             ((get-buffer-window buffer (selected-frame)))
             ((window-in-direction direction))
             (t
               (split-window (selected-window) size direction pixelwise)))))
    (window--display-buffer buffer window 'window alist display-buffer-mark-dedicated)
    window))

(defun dired-display-buffer (&optional direction alist)
"Display a dired-mode buffer or a file underneath point in a dired-mode buffer."
(interactive)
  (let* ((file-or-dir (or (and (eq major-mode 'dired-mode) (dired-get-file-for-visit))
                               (read-directory-name "Directory:  ")))
         (buffer (find-file-noselect file-or-dir))
         (direction
           (if direction
             direction
             (let ((char (read-char-exclusive (concat
                      "["
                      (propertize "l" 'face '(:foreground "red"))
                      "]"
                      (propertize "eft" 'face '(:foreground "blue"))
                      " | ["
                      (propertize "r" 'face '(:foreground "red"))
                      "]"
                      (propertize "ight" 'face '(:foreground "blue"))
                      " | ["
                      (propertize "a" 'face '(:foreground "red"))
                      "]"
                      (propertize "bove" 'face '(:foreground "blue"))
                      " | ["
                      (propertize "b" 'face '(:foreground "red"))
                      "]"
                      (propertize "elow" 'face '(:foreground "blue"))))))
                (cond
                  ((eq char ?l)
                    'left)
                  ((eq char ?r)
                    'right)
                  ((eq char ?a)
                    'above)
                  ((eq char ?b)
                    'below)
                  ;;; FIXME:  @lawlist may add a loop similar to `org-capture'
                  ;;; whereby a new `read-char-exclusive' will be initiated if
                  ;;; a user did not initially choose a valid option (l/r/a/b).
                  (t
                    (let ((debug-on-quit nil)
                          (msg (concat "dired-display-buffer:  "
                                       "You did not select l/r/a/b "
                                       "-- exiting.")))
                      (signal 'quit `(,msg)))))))))
    (my-display-buffer buffer alist direction)))
lista de leis
fonte
Oh, isso é perfeito. Alguém pode me ajudar com a hidra simples para dired-mode-map, vinculada a oe depois hjklpara exibição acima / abaixo / esquerda / direita?
ILemming 07/11
oh eu acho que entendi: (defhydra dired-open (dired-mode-map "O" :exit t) "dired-open" ("j" dired-display-below "below") ("k" dired-display-above "above") ("h" dired-display-left "left") ("l" dired-display-right "left"))
iLemming 07/11
Pequena coisa sobre a abordagem - ela não salta para a janela recém-criada. Não consigo descobrir como forçá-lo.
ILemming 07/11
2
@Agzam - A função select-windowpode ser usada no final de cada my-display-buffer-...função. Como você pode ver, o resultado / valor que é lançado no final da última linha é window. Se você não precisa o resultado / valor a ser usado em conjunto com uma outra função, então é só embrulhar o window na última linha com isto: (select-window window). Faça isso com todas as quatro (4) funções - ie my-display-buffer-below,; my-display-buffer-above; my-display-buffer-left; e my-display-buffer-right.
lawlist
3

Sua pergunta não é clara e, portanto, corre o risco de ser encerrada. Você tem dois quadros ou um único quadro com duas janelas do Emacs? Sejam quais forem, se houver dois, cada um deles será dividido verticalmente? E o que você quer dizer com "dividir verticalmente"? O que você quer dizer com "painel"? O que você quer dizer com "it", em "tê-lo aberto no painel A"?

Um palpite é que você tem um único quadro do Emacs dividido em duas janelas do Emacs, A e B, com a janela A acima da janela B, a janela B é selecionada e a janela B está mostrando um buffer Dired.

oestá vinculado por padrão a dired-find-file-other-window. Se o acima palpite estiver correto, em seguida, oem um nome de arquivo em B deve abrir em A. Isto é o que eu vejo quando se inicia Emacs sem um arquivo de inicialização: emacs -Q. Você não vê isso?

Se esse não for o cenário, descreva claramente o que você está fazendo, passo a passo, começando com emacs -Q.

Desenhou
fonte
2
Depende do tamanho do quadro - um quadro grande resultará no comportamento descrito pelo OP; enquanto que um quadro menor resultará no comportamento descrito por Drew.
lawlist
Acho que é exatamente isso que está acontecendo. Quando conectado ao meu monitor externo com uma moldura grande, o que eu descrevi acontece, mas agora que estou em casa no meu laptop menor, ele pergunta como eu desejo - existe uma maneira de forçá-lo a não abrir outra janela?
Robert
Oi, Drew, desculpe, eu não estou totalmente atualizado sobre a linguagem do emacs no que diz respeito às diferenças entre uma moldura e janela. O que eu quis dizer na minha pergunta original (se agora entendi corretamente janelas e quadros) é que tenho um único quadro do emacs e duas janelas do emacs lado a lado (verticalmente Cx 3). Tudo funciona como pretendido quando estou no meu laptop e o quadro é pequeno, mas como a lista de leis apontou quando o quadro é grande, o que descrevo acontece.
Robert
Sim, é possível. No entanto, um cenário geral da display-bufferfamília de variáveis ​​afetará outras situações ainda não previstas. Você pode personalizar o display-buffer-alist, o que é um pouco confuso, mesmo para usuários experientes do Emacs. Existem variáveis ​​que controlam quando dividir janelas e tamanhos mínimos de janelas, e a lista continua. Para conter o surto, você pode aconselhar dired-find-file-other-windowcom uma versão limitada display-buffer-alist, mas deixarei essa resposta para outro participante do fórum. Há uma variedade de soluções. :)
lawlist
0

NOTA : As seguintes variáveis ​​são globais , o que significa que elas afetarão outras funções além disso dired-find-file-other-window. O usuário pode aconselhar a função em questão para não afetar globalmente outras funções. [No entanto, este autor deixará essa opção para outro participante do fórum.] Como alternativa, há outra resposta que este autor postou contendo funções personalizadas que podem ser usadas para não afetar mais nada.


A variável split-width-thresholdpossui uma sequência de documentos que afirma:

Minimum width for splitting windows sensibly.
If this is an integer, ‘split-window-sensibly’ may split a window
horizontally only if it has at least this many columns.  If this
is nil, ‘split-window-sensibly’ is not allowed to split a window
horizontally.

Definir o seguinte no .emacsarquivo alcançará o efeito desejado. O usuário também pode definir o valor para um número maior. O valor padrão é 160

(setq split-width-threshold nil)

Aqui está um link para a seção relevante no manual:

https://www.gnu.org/software/emacs/manual/html_node/emacs/Window-Choice.html


Consulte também a variável relacionada split-height-threshold, que tem um valor padrão de 80

A sequência de documentos declara:

Minimum height for splitting windows sensibly.
If this is an integer, `split-window-sensibly' may split a window
vertically only if it has at least this many lines.  If this is
nil, `split-window-sensibly' is not allowed to split a window
vertically.  If, however, a window is the only window on its
frame, `split-window-sensibly' may split it vertically
disregarding the value of this variable.
lista de leis
fonte
Isso realmente funcionou muito bem! Agora, se algo engraçado começar a acontecer, pelo menos eu sei onde procurar. Obrigado novamente!
Robert