Emacs version 25

I have a short piece of elisp to create a few buffers and split my frame into multiple windows that are displayed the way I like. This code creates a *compilation* buffer and dedicates it using this code:

;; https://stackoverflow.com/questions/5151620/how-do-i-make-this-emacs-frame-keep-its-buffer-and-not-get-resized
;; Toggle window dedication
(defun toggle-window-dedicated ()
  "Toggle whether the current active window is dedicated or not"
  (interactive)
  (message
   (if (let (window (get-buffer-window (current-buffer)))
         (set-window-dedicated-p window
                                 (not (window-dedicated-p window))))
       "Window '%s' is dedicated"
     "Window '%s' is normal")
   (current-buffer)))

(switch-to-buffer (get-buffer-create "*compilation*"))
(toggle-window-dedicated)

My issue is that when running a compilation, even if the compiler output goes to the correct buffer, the *compilation* buffer doesn't scroll automatically to always display the most recent text.

My configuration is (setq compilation-scroll-output 'first-error)

The normal scrolling behavior seems to only be enabled when the *compilation* buffer is created by the compile command and not by hand. Even if I make the window with this buffer dedicated latter.

Is there a correct way to create the *compilation* buffer without running the compile command but keeping the compilation-scroll-output configuration behavior?

EDIT: a more detailed procedure:

How to trigger the problem:

  • put mybuffer.el and Makefile in one directory (/tmp/emacs_problem for example)
  • open file mybuffer.el
  • go to end of the create-my-buffers function and execute the code (C-x C-e)
  • execute the create-my-buffers function with M-x create-my-buffers
  • execute M-x compile RET RET

How to see the expected behavior:

  • open file mybuffer.el
  • execute M-x compile RET RET

The Makefile:

default:
    ls -1 /bin

mybuffer.el:

(defun create-my-buffers ()
  (interactive)
  (delete-other-windows)

  (setq total-window-size (window-width (frame-selected-window)))
  (setq total-window-height (window-height (frame-selected-window)))

  (split-window-vertically)
  (other-window 1)
  (switch-to-buffer (get-buffer-create "*compilation*"))
  (setq second-window-height (window-height (frame-selected-window)))
  (setq expected-window-height (* 0.10 total-window-height))
  (setq expand-window-height (- expected-window-height second-window-height))
  (enlarge-window (round expand-window-height))
  (other-window 1)
)

The result with the "bad" behavior, the window with the compilation buffer has not scrolled to the bottom: The result with the "bad" behavior, the window with the compilation buffer has not scrolled to the bottom

The result with the good behavior, the cursor is at the end of the content and the window has scrolled correctly: The result with the good behavior, the cursor is at the end of the content and the window has scrolled correctly

The output for M-x describe-mode after calling M-x compile is:

Enabled minor modes: Auto-Composition Auto-Compression Auto-Encryption
Autopair-Global Column-Number Company Company-Quickhelp
Company-Quickhelp-Local Delete-Selection Display-Time Electric-Indent
Evil-Matchit File-Name-Shadow Font-Lock Global-Auto-Revert
Global-Company Global-Eldoc Global-Evil-Matchit Global-Font-Lock
Global-Git-Gutter Global-Linum Global-Undo-Tree Global-Visual-Line
Global-Whitespace Hl-Line Line-Number Mouse-Wheel Save-Place
Shell-Dirtrack Show-Paren Tooltip Transient-Mark Undo-Tree Visual-Line

(Information about these minor modes follows the major mode info.)

Compilation mode defined in ‘compile.el’:
Major mode for compilation log buffers.
To visit the source for a line-numbered error,
move point to the error message line and type RET.
To kill the compilation, type C-c C-k.

Runs ‘compilation-mode-hook’ with ‘run-mode-hooks’ (which see).

EDIT 2: It seems that the scrolling is done correctly if I launch M-x compile from the window containing *compilation* rather than from the window containing mybuffer.el.

  • Just creating a buffer named *compilation* won't work. You also have to enable some compilation mode. Not at my computer, so couldn't help more. – Kaushal Modi Oct 18 '17 at 12:09
  • The problem is here even if I set the compilation mode using (compilation-mode) just after the switch-to-buffer. Also, the compilation mode will be set automatically if I don't set it by hand when I launch the first compilation. I took screenshots of the two buffers: imgur.com/gallery/muHuu – Louis Roché Oct 19 '17 at 6:44
  • I don't follow. Can you provide a full recipe to recreate your problem? Currently you just have code about toggling dedicated window and creating the *compilation* buffer. You'll need to enlist the full steps for anyone to recreate the issue you are seeing. – Kaushal Modi Oct 19 '17 at 9:52
  • Nitpick: you say "the *compilation* buffer doesn't scroll", but in reality, buffers don't scroll, windows do. I believe this difference is key to understanding your problem. As Klaushal says, you don't provide enough info to solve your problem, but I suspect it has something to do with the fact that M-x compile doesn't setup the window you're using (maybe it sets up another window which displays the same buffer?). – Stefan Oct 20 '17 at 14:23
  • Ok I tried to put everything needed in this gist. Please let me know if anything is missing. gist.github.com/Khady/d569687312e4950f86b0335e81ac60c0 – Louis Roché Oct 23 '17 at 5:56

revision:

Since I wasn't able to recreate my former success (see the comments below), the only answer I can offer is that the output scrolling works only in two cases: either, if you run the compilation command from the compilation buffer, or, if you re-use the compilation buffer for a second compilation.

It is not clear to me why any setup with (compilation-mode "Compilation") or (compilation-setup) does not work; it seems to ignore any customized variables when the compile command does not create the buffer itself. Maybe this can be considered a bug and should be put into the Emacs bug tracker at gnu.org, if it is not already there. The instance when I was able to make it work must have been a lucky shot, but, as already said, I cannot recreate what I did manually –– sorry.

  • Except that: 1. If I set the mode using (compilation-mode) just after the switch-to-buffer line, the result is the same. 2. The compilation mode is set automatically by M-x compile on the *compilation* buffer. You can see on the screenshot that the major mode is the good one because of Compilation:exit [0] IIUC. – Louis Roché Oct 24 '17 at 1:48
  • hmm… are you sure that it is the fully-fledged mode and not simply a mode title update? – user17303 Oct 24 '17 at 1:57
  • When I run M-x describe-mode on my *compilation* buffer after M-x compile, I think it tells that I'm using a compilation mode. But I don't know if it is the correct one. I added the output of describe-mode to the original question. – Louis Roché Oct 24 '17 at 2:07
  • Just played around a bit with this again and found something in compile.el. Insert (compilation-setup t) right after the buffer creation. Then it works. – user17303 Oct 24 '17 at 2:15
  • I don't manage to get it work. When you say right after the buffer creation, you mean after the switch-to-buffer line? – Louis Roché Oct 24 '17 at 2:25

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.