Ventana dividida en el borde exterior

8

Estoy buscando una manera de agregar una nueva división de ventana de altura completa a una configuración de ventana existente (dividida). Como no sé cómo explicarlo correctamente, simplemente publicaré algunos gráficos ASCII que muestran el comportamiento deseado para dos configuraciones de ventana de ejemplo:

             from                              to  

  +-------------------------+      +---------------------+---+  
  |                         |      |                     |   |  
  |                         |      |                     |   |  
  |            A            |  =>  |           A         | E |  
  |                         |      |                     |   |  
  |                         |      |                     |   |  
  +-------------------------+      +---------------------+---+  

  +------------+------------+      +----------+----------+---+  
  |            |     B      |      |          |   B      |   |
  |     A      +------------+      |     A    +----------+   |
  |            |     C      |  =>  |          |   C      | E | 
  +------------+------------+      +----------+----------+   |
  |            D            |      |          D          |   |
  +-------------------------+      +---------------------+---+  

donde la función acepta la anchura deseada de la nueva ventana Ey se contrae las anchuras de A, B, C, y Den consecuencia. Edit2 : Tenga en cuenta que los dos dibujos anteriores son ejemplos del comportamiento esperado para un caso concreto. Estoy buscando una función general que haga esto independientemente de la configuración en la columna desde (es decir, el número de ventanas [divisiones] en la columna desde debe ser arbitrario).

También estoy buscando esta funcionalidad en el lado izquierdo y en la parte superior e inferior de un marco.

Editar: Del comentario de @ Nsukami_ me di cuenta de que la funcionalidad que estoy buscando es un caso especial de un problema más abstracto. Así que voy a expresar ese problema:

¿Cómo almacena una configuración de ventana (que consta de cualquier número de ventanas y buffers) y "pega" la configuración almacenada en una ventana existente?

El "pegar" debería preservar los tamaños de ventana relativos y la división; naturalmente, la configuración pegada resultante es una copia escalada.

elemakil
fuente
El primer comportamiento se puede obtener pasando el argumento de tamaño a split-window-rightas C-u -width C-x 3. Cambie widtha lo que quiera y observe el signo negativo.
Vamsi
Estoy pensando en predefinir algunos diseños, pero no estoy seguro.
Nsukami _
@Nsukami_ ¿Es posible almacenar un diseño de ventana (por ejemplo, el diseño de A, B, C, y D) y luego insertar este diseño en una nueva ventana? Entonces mi problema podría resolverse 1) almacenando la configuración actual de la ventana, 2) cambiando el diseño para mostrar solo una ventana que luego se divide horizontalmente [esencialmente formando la ventana Ey la ventana de marcador de posición para las otras, llamémosla Z], 3 ) finalmente inserción del diseño original en la ventana izquierda ( Z)
elemakil
Tendrá que ajustar el diseño antes de la inserción, ya que también contienen los tamaños de las ventanas. Además, la inserción de un diseño en una ventana en particular no es posible sin elisp personalizado AFAIK
Vamsi

Respuestas:

5

La siguiente función debe hacer lo que quieras. El truco es dividir la ventana raíz del marco actual.

(defun my-split-main-window (direction size)
  "Split the main window in the DIRECTION where DIRECTION is a symbol with
possible values of right, left, above or below and SIZE is the final size of the
windows, if the window is split horizontally (i.e. in DIRECTION below or above)
SIZE is assumed to be the target height otherwise SIZE is assumed to be the
target width"
  (let* ((new-window (split-window (frame-root-window) nil direction))
         (horizontal (member direction '(right left))))
    (save-excursion 
      (select-window new-window)
      (enlarge-window (- size (if horizontal
                                  (window-width)
                                (window-height)))
                      horizontal))
    new-window))

Llame a la función con la dirección en la que desea dividir la ventana y el tamaño de la nueva ventana. Lo anterior devuelve la ventana recién creada. El concepto, las ventanas y los marcos se explican muy bien en el Manual de referencia de GNU Emacs Lisp .

Iqbal Ansari
fuente
¡Perfecto! Esto es justo lo que quería.
elemakil
0

No estoy seguro de si la mejor solución, ya que no está lo suficientemente resumida, en realidad solo estoy resolviendo un caso de uso. El truco es escribir una función para ir de layoutX a layoutY, y otra para ir de layoutY a layoutX

(defun from-x-to-y ()
 (interactive)
 (delete-other-windows)
 (split-window-vertically) ;;
 (let ((current-prefix-arg 10)) ;; emulate C-u
   (call-interactively 'enlarge-window) ;; resize
   )
 (split-window-horizontally) ;; -> |
 (next-multiframe-window)
 (split-window-vertically) ;;  -> --
 (previous-multiframe-window)
)

(defun from-y-to-x ()
  (interactive)
  (delete-other-windows)
  (split-window-horizontally) ;; -> |
  (let ((current-prefix-arg -60)) ;; emulate C-u
    (call-interactively 'shrink-window-horizontally) ;; resize
    )
  (split-window-vertically) ;; -> --
  (let ((current-prefix-arg 10)) ;;
    (call-interactively 'enlarge-window) ;;
    )
  (split-window-horizontally) ;;
  (next-multiframe-window)
  (split-window-vertically) 
  (previous-multiframe-window)
)

Espero que esa solución ayude

¿Cómo almacena una configuración de ventana (que consta de cualquier número de ventanas y buffers) y "pega" la configuración almacenada en una ventana existente?

Acabo de encontrar un paquete llamado layout.el , nunca lo he usado pero parece ser lo que estás buscando, nos dirás si está bien.

EDITAR:

Intentando encontrar una solución más genérica, parece que puede usar M-x switch-to-buffer-other-framepara pasar de un búfer en un marco, digamos con un diseño X, a otro búfer en otro marco con un diseño Y.

También puede estar en un diseño X, almacenar este diseño en un registro C-x r f(frame-configuration-to-register), ir a otro diseño y, cuando sea necesario, volver al anterior, llamando con qué dentro del registro C-x r j (jump- para registrarse)

Nsukami _
fuente
Por lo que puedo decir, layout.elhace algo similar a winner: (re) almacenar la configuración de la ventana del cuadro completo, no almacenar la configuración completa y restaurarla en una ventana existente. Por otro lado, la función que escribió no son las soluciones generales que estoy buscando. Resuelven mi segundo ejemplo, que no fue el problema concreto sino solo un ejemplo. Estoy buscando una solución que funcione en el caso general.
elemakil
Todavía estoy cavando, y creo que la solución general podría ser switch-to-buffer-other-framesi 'from' es un marco y 'to' es otro marco
Nsukami _