Cómo usar "o" para abrir desde dired / ibuffer a otro marco

8

Tengo dos ventanas abiertas y divididas verticalmente (marco único):

A) contiene mi trabajo
B) contiene dired o ibuffer.

Me gustaría poder navegar a un archivo / búfer en el panel B y presionar "o" para que se abra en el panel A. ¿Es esto posible? En este momento, emacs está creando un nuevo panel en la parte inferior del panel A para abrir el archivo.

editar: de acuerdo con la lista de leyes del usuario, el comportamiento descrito anteriormente ocurrirá cuando el marco sea grande. Este parece ser el caso para mí porque ahora que estoy en casa (no en un monitor externo, marco más pequeño), emacs se comporta como lo deseo. La pregunta ahora es: ¿puedo evitar que emacs abra una nueva ventana cuando el marco actual es grande?

Robert
fuente
1
Bienvenido al foro beta de Emacs. Como parte de la jerga / jerga de Emacs, usamos la palabra windowpara referirnos a un cuadrante de búfer dentro del mismo frame. Se frameconsidera que A es todo el gatito-kaboodle, que puede tener muchas ventanas dentro. Emacs puede generar múltiples cuadros, cada cuadro contiene múltiples ventanas.
abogados
¡gracias por la aclaración! He sido un usuario de emacs desde hace mucho tiempo, pero nunca he entendido completamente la terminología.
Robert

Respuestas:

6

Aquí hay cuatro (4) ejemplos de display-bufferfamilias de funciones personalizadas que se pueden personalizar para satisfacer las necesidades particulares de un usuario, arriba ; abajo ; la izquierda ; derecha - y aquí hay cuatro (4) interactivefunciones para mostrar el archivo o directorio de la línea actual de un dired-modebúfer. Solo hay tres condiciones: (a) si ya hay una ventana que muestra el búfer de destino, elíjalo; (b) si hay una ventana en la dirección deseada que está disponible, úsela; (c) el objetivo general es crear una nueva ventana en la dirección deseada si no se cumplen las otras condiciones.

Uso:

M-x dired-display-above

M-x dired-display-below

M-x dired-display-left

M-x dired-display-right

Hay tantas combinaciones de teclas ya integradas dired-modey dired+, que no me atrevo a inventar las mías. El usuario es libre de elegir sus propios atajos de teclado, lo que está más allá del alcance de este ejemplo limitado.

El usuario es libre de agregar condiciones adicionales a la display-bufferfamilia de funciones de muestra para manejar más situaciones, por ejemplo, más ventanas que solo un par.

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

EDITAR: Aquí hay una implementación un poco más sofisticada / divertida del concepto anterior, que le da al usuario la capacidad de usar esto de manera no interactiva o interactiva ; por ejemplo, M-x dired-display-buffer- donde se le pedirá al usuario que elija un directorio si no se encuentra sobre un archivo dired-modey que elija una dirección de visualización (izquierda, derecha, arriba, abajo).

(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 leyes
fuente
oh esto es perfecto ¿Alguien puede ayudarme con una hidra simple para dired-mode-map, unida oy luego hjklpara mostrar arriba / abajo / izquierda / derecha?
iLemming el
oh, creo que lo tengo: (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
Pequeña cosa sobre el enfoque: no salta a la ventana recién creada. No puedo entender cómo forzarlo.
iLemming el
2
@Agzam: la función select-windowse puede utilizar al final de cada my-display-buffer-...función. Como puede ver, el resultado / valor que se arroja al final de la última línea es window. Si usted no necesita el resultado / valor para utilizar en conjunción con otra función, a continuación, sólo envolver el window de la última línea con esto: (select-window window). Haga eso con las cuatro (4) funciones, es decir my-display-buffer-below; my-display-buffer-above; my-display-buffer-left; y my-display-buffer-right.
abogados
3

Su pregunta no está clara, por lo que corre el riesgo de ser cerrada. ¿Tiene dos cuadros o un solo cuadro con dos ventanas Emacs? Cualesquiera que sean, si hay dos, ¿ cada uno de ellos está dividido verticalmente? ¿Y qué quieres decir con "dividir verticalmente"? ¿Qué quieres decir con un "panel"? ¿Qué quiere decir con "eso" en "tenerlo abierto en el panel A"?

Una suposición descabellada es que tiene un solo cuadro de Emacs que se divide en dos ventanas de Emacs, A y B, con la ventana A encima de la ventana B, la ventana B está seleccionada y la ventana B muestra un búfer Dired.

oestá vinculado por defecto a dired-find-file-other-window. Si lo anterior suposición es correcta, entonces oen un nombre de archivo en B debe abrir en A. Esto es lo que veo cuando se inicia Emacs sin un archivo de inicio: emacs -Q. ¿No lo ves?

Si este no es el escenario, describa claramente lo que está haciendo, paso a paso, comenzando con emacs -Q.

Dibujó
fuente
2
Depende del tamaño del marco: un marco grande dará como resultado el comportamiento descrito por el OP; mientras que un marco más pequeño dará como resultado el comportamiento que Drew describió.
abogados
Lawlist Creo que eso es exactamente lo que está sucediendo. Cuando lo conecto a mi monitor externo con un marco grande, lo que describí sucede, pero ahora que estoy en casa en la pantalla de mi computadora portátil más pequeña, pregunta como deseo: ¿hay alguna manera de forzarlo a no abrir otra ventana?
Robert
Hola, Drew, lo siento, no estoy completamente al día con la jerga de emacs con respecto a las diferencias entre un marco y una ventana. Lo que quise decir en mi pregunta original (si ahora entiendo las ventanas y los marcos correctamente) es que tengo un solo marco emacs y dos ventanas emacs una al lado de la otra (verticalmente Cx 3). Todo funciona según lo previsto cuando estoy en mi computadora portátil y el marco es pequeño, pero como señaló la lista de leyes cuando el marco es grande, sucede lo que describo.
Robert
Sí, es posible. Sin embargo, una configuración general de la display-bufferfamilia de variables afectará otras situaciones aún no previstas. Puede personalizarlo display-buffer-alist, lo cual es algo confuso incluso para usuarios experimentados de Emacs. Hay variables que controlan cuándo dividir ventanas y tamaños mínimos de ventanas, y la lista sigue y sigue. Para contener el brote, puede aconsejar dired-find-file-other-windowcon una versión limitada del display-buffer-alist, pero dejaré esa respuesta a otro participante del foro. Hay una variedad de soluciones. :)
lawlist
1

NOTA : Las siguientes variables son globales , lo que significa que afectarán otras funciones además dired-find-file-other-window. El usuario puede desear aconsejar la función en cuestión para no afectar globalmente a otras funciones. [Sin embargo, este autor dejará esa opción a otro participante del foro.] Alternativamente, hay otra respuesta que este autor publicó que contiene funciones personalizadas que se pueden utilizar para no afectar nada más.


La variable split-width-thresholdtiene una cadena de documentación que establece:

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.

Establecer lo siguiente en el .emacsarchivo logrará el efecto deseado. El usuario también puede establecer el valor en un número mayor. El valor predeterminado es 160

(setq split-width-threshold nil)

Aquí hay un enlace a la sección correspondiente en el manual:

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


Consulte también la variable relacionada split-height-threshold, que tiene un valor predeterminado de 80

Los estados de la cadena de documentación:

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 leyes
fuente
¡Esto realmente funcionó bastante bien! Ahora, si algo divertido comienza a suceder, al menos sé dónde mirar. ¡Gracias de nuevo!
Robert