¿Cómo alternar entre dos ventanas cuando tengo más de dos abiertas?

8

Escenario: Tengo varias (más de 2) ventanas abiertas. Trabajo activamente con dos de ellos. ¿Cómo salto mejor de una ventana a otra, y de regreso, con un comando?

Yo uso ace-window; es genial, pero no quiero presionar el número de la ventana cada vez. Sé sobre next-window/ prev-window, pero estos son dos comandos diferentes.

Lo que estoy buscando es algo que recuerde cuál era la ventana anterior cuando seleccioné otra ventana, y vuelve a ella. Invocado repetidamente, cambiaría entre las dos últimas ventanas, Alt- Tab-style.

Donde miro

9000
fuente
Utilizo fnmás una de las teclas de flecha para ir en cualquier dirección, incluso dentro y fuera del minibúfer (si está activo); vea la biblioteca incorporada windmove.
abogados el
@lawlist: sé sobre windmove. Lo que estoy buscando es una manera de no pensar en la dirección requerida, especialmente si las ventanas tienen algunas otras ventanas entre ellas.
9000

Respuestas:

6

Una forma de escribir su propio comando es usar la get-mru-windowfunción integrada.

Por ejemplo:

(defun my-flip-window ()
  (interactive)
  (let ((win  (get-mru-window nil nil t)))
    (when win (select-window win))))

Esto busca la ventana utilizada más recientemente en el marco actual que no es la ventana seleccionada actualmente.

Aquí hay una variación que funciona en los marcos visibles:

(defun my-flip-window ()
  (interactive)
  (let ((win  (get-mru-window 'visible nil t)))
    (when win
      (select-frame-set-input-focus (window-frame win))
      (select-window win))))

Como se menciona en los comentarios, aquí hay una variación que funciona cuando solo hay una ventana (cambiar al búfer más reciente):

(defun flip-window ()
  (interactive)
  (let ((win  (get-mru-window 'visible t t)))
    (if win
        (progn
          (select-frame-set-input-focus (window-frame win))
          (select-window win))
      (mode-line-other-buffer))))
glucas
fuente
1
¡Justo en el clavo! Este es mucho mejor que el que armé. Buen hallazgo en get-mru-window.
Dan
1
Terminé agregando esto a mi configuración con una variación adicional: cuando solo hay un marco / ventana (get-mru-window devuelve nil), luego llame mode-line-other-buffer. De esa manera, tengo una tecla que se mueve de un lado a otro entre dos buffers en cualquier configuración de ventana.
glucas
Excelente. Me encanta esa última variación @glucas. Gracias. Así es como lo escribí y funciona. ¿Es esa la mejor manera de hacerlo? (defun my-switch-to-previous-window () (interactivo) (let ((win (get-mru-window nil nil t)))) (if win (select-window win) (mode-line-other-buffer ))))
prosoitos
6

Si ya está usando ace-window, puede usar el comando aw-flip-windowpara alternar entre dos ventanas. Por defecto, esto está vinculado a nla ventana ace aw-dispatch-alist.

Eso significa que puede invocar ace-window y presionar en nlugar de un número de ventana para volver a la ventana anterior. También puede vincular aw-flip-windowa alguna otra clave.

Tenga en cuenta que esto solo volverá a una ventana que previamente fue seleccionada por ace-window. Si a menudo cambia ventanas con otros comandos, es posible que desee una solución más general.

glucas
fuente
4

Aquí hay un comando simple, ligeramente probado, que lo cambiará a la ventana visitada más recientemente:

(defvar recent-window nil
  "The most recently visited window.")

(defun switch-to-recent-window ()
  "Switch to the most recently visited window, as stored in
`recent-window'."
  (interactive)
  (let ((current (car (window-list))))
    (if recent-window
        (select-window recent-window)
      (message (concat "No recent window selected, "
                       "so I'm setting this window "
                       "as the most recent.")))
    (setq recent-window current)))
Dan
fuente
¡Gracias! Funciona. ¿Te importa si hago un paquete con atribución?
9000
De nada. Claro, siéntase libre de usarlo en un paquete, pero tenga en cuenta que el código no es (todavía) muy inteligente. Si cambia a otras ventanas con comandos como next-windowo other-window, el cambio no se recogerá en la recent-windowvariable. No hay un gancho obvio para usar, por lo que arreglar esta parte puede implicar definir consejos para muchas otras funciones.
Dan
1
Creo que podría usar buffer-list-update-hook, que se llama cuando cambia la ventana activa (después select-window). Ese gancho se llama en otros casos, pero podría usarse para realizar un seguimiento de la última ventana.
glucas