Question

Im new to xemacs and linux in general, so consider me a newbie. And i was wondering if there is a reason why elisp wouldn't execute a command or commands instantly.

I've the following code in my init.el:

(defun myClear ()
  "Clears console output buffer (F5)"
  (erase-buffer "*Shell Command Output*"))

(defun myMake ()
  "Executes make (F6)"
  (shell-command "make"))

(defun myClearMake ()
  "Clears console output buffer before executing make (F7)"
  (erase-buffer "*Shell Command Output*")
  (shell-command "make"))

they are bound to the keys F5-F7. Hitting F7 does not produce the same result as hitting F5 first, then F6, which work as expected.

What happens instead is that the (erase-buffer ...) statement seems to be skipped, or maybe executed right before (shell-command ...). Since shell-command erases the buffer before dumping shell output anyway, its hard to tell.

What i expected: The console output gets cleared. This should be visible while make is still running and has not produced any output yet (which, in my case, is several seconds).

I have no idea how to further test this, and even though it seems like a common task, i couldn't find anything appropriate, or similar. Also consider that i'm not only interested in getting the mentioned behaviour, but also understanding what i did wrong.

Any links/pointer on elisp mechanics that explain this behaviour are appreciated. Thanks, Tasche

Was it helpful?

Solution

First, I'm not much used to XEmacs, but rather to Emacs... There might be differences. But I can reproduce your problem with Emacs, so I hope the Emacs solution will also work for XEmacs.

Emacs doesn't redisplay the UI during command execution, which means hitting F5 runs command myClear, then redraws the display while waiting for another input, then myMake is executed when you hit F6. On the other hand, when you hit F7, the entire cycle myClear-myMake is executed, without any redisplay, making erase-buffer effects invisible. You eed to force a redisplay after erase-buffer to see its effects.

Below is a working example based on the code which you provided.

(defun myClear ()
  "Clears console output buffer (F5)"
  (interactive)
  (with-current-buffer "*Shell Command Output*"
    (erase-buffer)))

(defun myMake ()
  "Executes make (F6)"
  (interactive)
  (shell-command "sleep 2; echo Hello World"))

(defun myClearMake ()
  "Clears console output buffer before executing make (F7)"
  (interactive)
  (myClear)
  (redisplay)
  (myMake))

(global-set-key (kbd "<f5>") 'myClear)
(global-set-key (kbd "<f6>") 'myMake)
(global-set-key (kbd "<f7>") 'myClearMake)

Note that I had to do minor adjustments (maybe due to Emacs/XEmacs differences?)

Also note that a better way to do things like running make consists in using M-xcompileRET. In particular, this will take care of erasing the buffer for you, run processes in the background (without hanging Emacs like your example does), and process the output to detect error/warning messages.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top