Как сделать окно компиляции в Emacs всегда определенным размером?

Я хочу, чтобы окно компиляции в Emacs всегда отображалось в нижней части окна и всегда было определенной высотой. До сих пор я помещал следующие строки в мой файл .emacs:

(setq split-height-threshold 0)
(setq compilation-window-height 10)

... и это работает, когда у меня открыто только одно окно, но как только я разбиваю экран на два окна по горизонтали (то есть разделительная линия в середине идет сверху вниз) окно компиляции перестает уважать переменную высоты и разбивает окно прямо посередине.

Как это исправить?

Ответ 1

Я бы использовал что-то вроде этого, свободно адаптированное из EmacsWiki:

(defun my-compilation-hook ()
  (when (not (get-buffer-window "*compilation*"))
    (save-selected-window
      (save-excursion
        (let* ((w (split-window-vertically))
               (h (window-height w)))
          (select-window w)
          (switch-to-buffer "*compilation*")
          (shrink-window (- h compilation-window-height)))))))
(add-hook 'compilation-mode-hook 'my-compilation-hook)

Если буфер *compilation* не отображается, это будет разбивать окно по вертикали, изменить размер вновь открытого окна на 10 строк и открыть в нем буфер *compilation*.

Ответ 2

Вы можете настроить переменную compilation-window-height.

Ответ 3

Объединение кода из Как я могу запретить emacs открывать новое окно для вывода компиляции? и код из http://www.emacswiki.org/emacs/CompilationMode, это все мой код для compile, он предоставляет вам 4 функции:

1). Используйте compile-again для запуска того же компиляции, что и в последний раз, автоматически, без подсказки. Если в последний раз нет или существует префиксный аргумент, он действует как компиляция M-x.

2). compile разделит текущее окно (всегда будет определенный размер), это не повлияет на другие окна в этом фрейме.

3). он автоматически закроет буфер *compilation* (окно), если нет ошибки, сохраните его, если существует ошибка.

4). он выделит строку ошибки и номер строки исходного кода в буфере *compilation*, используйте M-n/p для навигации по каждой ошибке в буфере *compilation*, Enter в строке ошибки, чтобы перейти к строке в коде кода.

(require 'compile)
(setq compilation-last-buffer nil)
(defun compile-again (ARG)
  "Run the same compile as the last time.

If there is no last time, or there is a prefix argument, this acts like M-x compile."
  (interactive "p")
  (if (and (eq ARG 1)
           compilation-last-buffer)
      (progn
        (set-buffer compilation-last-buffer)
        (revert-buffer t t))
    (progn
      (call-interactively 'compile)
      (setq cur (selected-window))
      (setq w (get-buffer-window "*compilation*"))
      (select-window w)
      (setq h (window-height w))
      (shrink-window (- h 10))
      (select-window cur))))
(global-set-key (kbd "C-x C-m") 'compile-again)
(defun my-compilation-hook ()
  "Make sure that the compile window is splitting vertically."
  (progn
    (if (not (get-buffer-window "*compilation*"))
        (progn
          (split-window-vertically)))))
(add-hook 'compilation-mode-hook 'my-compilation-hook)
(defun compilation-exit-autoclose (STATUS code msg)
  "Close the compilation window if there was no error at all."
  ;; If M-x compile exists with a 0
  (when (and (eq STATUS 'exit) (zerop code))
    ;; then bury the *compilation* buffer, so that C-x b doesn't go there
    (bury-buffer)
    ;; and delete the *compilation* window
    (delete-window (get-buffer-window (get-buffer "*compilation*"))))
  ;; Always return the anticipated result of compilation-exit-message-function
  (cons msg code))
(setq compilation-exit-message-function 'compilation-exit-autoclose)
(defvar all-overlays ())
(defun delete-this-overlay(overlay is-after begin end &optional len)
  (delete-overlay overlay)
  )
(defun highlight-current-line ()
"Highlight current line."
  (interactive)
  (setq current-point (point))
  (beginning-of-line)
  (setq beg (point))
  (forward-line 1)
  (setq end (point))
  ;; Create and place the overlay
  (setq error-line-overlay (make-overlay 1 1))

  ;; Append to list of all overlays
  (setq all-overlays (cons error-line-overlay all-overlays))

  (overlay-put error-line-overlay
               'face '(background-color . "red"))
  (overlay-put error-line-overlay
               'modification-hooks (list 'delete-this-overlay))
  (move-overlay error-line-overlay beg end)
  (goto-char current-point))
(defun delete-all-overlays ()
  "Delete all overlays"
  (while all-overlays
    (delete-overlay (car all-overlays))
    (setq all-overlays (cdr all-overlays))))
(defun highlight-error-lines(compilation-buffer process-result)
  (interactive)
  (delete-all-overlays)
  (condition-case nil
      (while t
        (next-error)
        (highlight-current-line))
    (error nil)))
(setq compilation-finish-functions 'highlight-error-lines)

Ответ 4

Там отличный пакет для таких ситуаций, который называется Shackle. https://github.com/wasamasa/shackle

Легко настроить и работает практически на любом типе буфера