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

Если в emacs отображается только одно окно, и я использую компиляцию M-x, окно разделяется на две части, и я могу легко наблюдать за буфером компиляции. Однако, если у меня отображается больше окон, журнал компиляции заменяет одно из других, что меня раздражает. Как я могу заставить emacs всегда разделять новое окно для отображения журнала компиляции?

Изменить: немного больше информации из того, что я читал. Похоже, что compile.el вызывает display-buffer, который разбивает окно только в том случае, если оно имеет текущую полную ширину. Есть ли способ избежать такого поведения?


person Josh Matthews    schedule 13.04.2009    source источник


Ответы (4)


Вы можете изменить решение, предоставленное Трей Джексон в соответствии с вашими потребностями.

Следующий фрагмент отмечает буфер *compilation* как специальный и устанавливает настраиваемую функцию в качестве функции отображения для разделения текущего окна, даже если оно уже находится в разделенном окне.

(setq special-display-buffer-names
      '("*compilation*"))

(setq special-display-function
      (lambda (buffer &optional args)
        (split-window)
        (switch-to-buffer buffer)
        (get-buffer-window buffer 0)))
person viam0Zah    schedule 14.04.2009

Если вам нужно специальное окно верхнего уровня (Emacs называет эти фреймы), то это поможет вам. Этот фрагмент включает директивы размещения, но настройка переменной 'special-display-buffer-names даст вам то, что вы хотите.

(setq special-display-buffer-names
      `(("*compilation*" . ((name . "*compilation*")
                            ,@default-frame-alist
                            (left . (- 1))
                            (top . 0)))))
person Trey Jackson    schedule 14.04.2009
comment
Я знаю терминологию и на самом деле ищу логическое окно emacs, а не физическое. - person Josh Matthews; 14.04.2009

Объединение кода из Как можно ли запретить 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)
person CodyChan    schedule 01.02.2015

Установите пакет smart-compile внутри Emacs.

добавьте это в свой init.el или .emacs

(require 'compile)
(setq compilation-last-buffer nil)
;; save all modified buffers without asking before compilation
(setq compilation-ask-about-save nil)
(defun compile-again (ARG)
  "Run the same compile as the last time.

With a prefix argument or no last time, this acts like M-x compile,
and you can reconfigure the compile args."
  (interactive "p")
  ;; the following two lines create bug: split a new window every time
  ;; (if (not (get-buffer-window "*compilation*"))
  ;;      (split-window-below))
  (if (and (eq ARG 1) compilation-last-buffer)
      (recompile)
    (call-interactively 'smart-compile)))
(bind-key* "C-x C-m" 'compile-again)
;; create a new small frame to show the compilation info
;; will be auto closed if no error
(setq special-display-buffer-names
      `(("*compilation*" . ((name . "*compilation*")
                            ,@default-frame-alist
                            (left . (- 1))
                            (top . 0)))))
(setq compilation-finish-functions
      (lambda (buf str)
        (if (null (string-match ".*exited abnormally.*" str))
            ;;no errors, make the compilation window go away in a few seconds
            (progn
              (run-at-time
               "1 sec" nil 'delete-windows-on
               (get-buffer-create "*compilation*"))
              (message "No Compilation Errors!")))))

Используйте C-x C-m для компиляции исходного кода. Если вы выполняете C-x C-m впервые, он попросит вас изменить команду по умолчанию (чего обычно достаточно), в противном случае он выполнит команду, которую вы только что использовали для компиляции напрямую, и вам придется используйте C-u C-x C-m, чтобы изменить команду, если хотите. Если у вас есть Makefile внутри текущего каталога, он заметит и предложит спросить, хотите ли вы его использовать.

Возможно, этот ответ слишком велик для вашего вопроса, но попробуйте.

person CodyChan    schedule 24.11.2016