¿Hay alguna forma de controlar en qué ventana Emacs abre nuevos buffers?


12

Estoy usando sr-speedbar con emacs, y a menudo tengo el marco dividido en 2-3 ventanas diferentes, y cada vez que hago clic en un archivo en sr-speedbar, siempre abre el nuevo búfer en la ventana más baja. Estoy tratando de mantener la ventana inferior derecha como un término ansi relativamente pequeño, y emacs sigue insistiendo en abrir nuevos buffers en la ventana a corto plazo en lugar de en el área mucho más grande que me gustaría usar para editar buffers.

¿Hay alguna forma de configurar la lógica de creación de búfer para preferir ventanas más altas que ventanas más bajas?

Ya intenté tomar mi ventana más baja y marcarla como protegida, y eso hizo que emacs la dividiera en dos porciones irrazonablemente pequeñas. Luego intenté habilitar window-size-fixed y, en lugar de hacer que emacs abriera el búfer sobre esa ventana, me dio un error de que la ventana era demasiado pequeña para dividirse. Bueno, supongo que dejó de golpear mi ventana más baja, pero tonto que me impidió abrir nuevos tampones.

Idealmente, me gustaría poder forzar a emacs a seleccionar la ventana superior derecha para mostrar los búferes recién creados, no intentar dividir la ventana inferior derecha.


Buena pregunta, espero que a alguien se le ocurra una respuesta.
cpoile

@cpoile lo hice! Mira mi respuesta.
Aaron Miller

Respuestas:


8

Supongo que estás usando Emacs 24; No he probado esta respuesta en ninguna versión anterior, y no sé cuándo se agregó el concepto de ventanas dedicadas a Emacs. He visto menciones de su uso que datan de 2011, por lo que supongo que Emacs 23 (al menos) también tiene la capacidad.

Puede evitar que Emacs abra un nuevo búfer en una ventana determinada dedicando la ventana a su búfer .

En el caso más simple, puede hacer esto seleccionando la ventana que desea dedicar, asegurándose de que actualmente muestre el búfer al que desea dedicar, y luego haciendo M-: (set-window-dedicated-p (selected-window) t). Esto evitará que Emacs considere la ventana tan modificada al decidir en qué ventana mostrar un búfer. Para eliminar la dedicación, evalúe la misma expresión, reemplazando el segundo argumento con nil.

Puede evitar que Emacs intente dividir una ventana que muestra un búfer determinado configurando la variable local del búfer tamaño-ventana-fijada en un valor no nulo.

En el caso más simple, puede hacer esto seleccionando la ventana y haciendo M-: (setq window-size-fixed t). Para corregir solo el alto o ancho de las ventanas que muestran el búfer, evalúe la misma expresión, pasando 'heighto 'widthcomo el segundo argumento; para eliminar la restricción, reemplace el segundo argumento con nil.

En el caso general, encontré su problema lo suficientemente interesante como para hackear una solución , que puede colocar en su ruta de carga (require)y usar:

;;; dedicate-windows-manually.el --- Manually (un)dedicate windows

;; Copyright (C) 2013 Aaron Miller
;; <me@aaron-miller.me>

;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2 of
;; the License, or (at your option) any later version.

;; This program is distributed in the hope that it will be
;; useful, but WITHOUT ANY WARRANTY; without even the implied
;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
;; PURPOSE.  See the GNU General Public License for more details.

;; You should have received a copy of the GNU General Public
;; License along with this program; if not, write to the Free
;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
;; MA 02111-1307 USA

;;; Commentary:

;; Introduction
;; ============

;; The functions here defined allow you to manually dedicate and
;; undedicate windows, that is, prevent `set-window-buffer' from
;; considering them when selecting a window in which to display a
;; given buffer.

;; Windows dedicated in this fashion will also be protected from
;; splitting by setting `window-size-fixed'.

;; Installation
;; ============

;; Place this file in your load path; then, place the following
;; command somewhere in your initialization file:

;; (require 'dedicate-windows-manually)

;; Now you can use M-x dedicate-window to dedicate the selected window
;; to its currently displayed buffer, M-x undedicate-window to release
;; a dedication so applied, and M-x dedicate-window-toggle to switch
;; between the states.

;; These functions will operate only on manually dedicated or
;; undedicated windows; that is, M-x dedicate-window will not dedicate
;; a window which is already dedicated (i.e. "(window-dedicated-p
;; window) -> t", and M-x undedicate-window will not undedicate a
;; window which was not dedicated by way of M-x dedicate-window.

;; If you find yourself frequently doing M-x dedicate-window-toggle,
;; you might wish to place something like this in your init file:

;; (global-set-key (kbd "C-x 4 C-d") 'dedicate-window-toggle)

;; Bugs:
;; * Changing the lighter string while you have windows dedicated is
;;   probably not a good idea.
;; * I should certainly find a better way to change the mode line.

;;; Code:

(defcustom dedicated-window-lighter-string " [D]"
  "A string, propertized with `dedicated-window-lighter-face', prepended
to the mode line of manually dedicated windows.")

(defvar dedicated-windows-by-hand nil
  "A list of windows known to have been manually dedicated. Windows not
in this list will not be undedicated by `undedicate-window'.")

(defun dedicate-window-was-by-hand-p (window)
  (let ((result nil))
    (loop for w in dedicated-windows-by-hand
          collect (if (eq w window) (setq result t)))
    result))

(defun dedicate-window (&optional window flag)
  "Dedicate a window to its buffer, and prevent it from being split.

Optional argument WINDOW, if non-nil, should specify a window. Otherwise,
or when called interactively, the currently selected window is used.

Optional argument FLAG, if non-nil, will be passed verbatim to
`set-window-dedicated-p'."
  (interactive nil)
  (if (eq nil window) (setq window (selected-window)))
  (if (eq nil flag) (setq flag t))
  (if (window-dedicated-p window)
      (message "Window is already dedicated.")
    (progn
      (add-to-list 'dedicated-windows-by-hand window)
      (setq mode-line-format
            (append `(,dedicated-window-lighter-string) mode-line-format))
      (setq window-size-fixed t)
      (set-window-dedicated-p window flag))))

(defun undedicate-window (&optional window)
  "Un-dedicate a window from its buffer.

Optional argument WINDOW, if non-nil, should specify a window listed in
`dedicated-windows-by-hand'. Otherwise, or when called interactively,
the currently selected window is used.

If WINDOW is not in `dedicated-windows-by-hand', a complaint will be
issued and nothing will be done."
  (interactive nil)
  (if (eq nil window) (setq window (selected-window)))
  (if (not (window-dedicated-p window))
      (message "Window is not dedicated.")
    (if (not (dedicate-window-was-by-hand-p window))
        (message "Window is not dedicated by hand.")
      (progn
        (setq dedicated-windows-by-hand
              (remove window dedicated-windows-by-hand))
        (setq mode-line-format
              (remove dedicated-window-lighter-string mode-line-format))
        (setq window-size-fixed nil)
        (set-window-dedicated-p window nil)))))

(defun dedicate-window-toggle (&optional window)
  "Toggle a window's manual buffer dedication state.

Optional argument WINDOW, if non-nil, should specify a window. Otherwise,
or when called interactively, the value of `selected-window' is used."
  (interactive nil)
  (if (eq nil window) (setq window (selected-window)))
  (if (window-dedicated-p window)
      (undedicate-window window)
    (dedicate-window window)))

(provide 'dedicate-windows-manually)

;;; dedicate-windows-manually.el ends here

4

En versiones recientes de Emacs display-buffer-alistse agregó la opción . Proporciona un control detallado sobre la visualización del búfer, las ventanas utilizadas, etc. Sin embargo, dado que le permite hacer muchas cosas, también es bastante complejo y difícil de describir. Consulte la documentación: C-h v display-buffer-alist.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.