开发者

can I disable the "(Type e to repeat macro)" message in emacs?

So, I've finally made the plunge, and have gotten to the state where I'm quite happy to have switched from vi and vim to emacs... I've been putting stuff in my .emacs file, learning how to evaluate things (not to mention becoming familiar with movement commands), etc. etc. etc.

And now I have a problem with a require line in my .emacs file (a require statement*), which bombs out when I launch emacs (and generally fails to work).

So, this lead me to the following situation:

In the process of trying to debug the above situation, one of the steps I did was to open the file I was trying to require, and evaluate it bit by bit, using C-M-f and C-x C-e (and later just M-x eval-buffer), which all worked fine. But along the way of the section-by-section, I got tired of typing all those, and so I recorded a keyboard macro... C-x ( C-M-f C-x C-e C-x ) and then C-x e... which gave me a message in the minibuffer (I think I'm using the right name), saying (Type e to repeat macro). Which meant I could no longer see the resultant value of the evaluation of each section of code... which, while not critical in this case, I was liking having.

Which leads me to the actual question:

Is there a way to disable that message, and/or to cause the minibuffer to show multiple lines at once?

I know about the *Messages* buffer, and that could have helped, I'm just wondering if there's a way to either disable that message, or otherwise make it coexist with other messages. Any suggestions?

Thanks!

  • lindes

* - the problem at hand, which i开发者_JS百科s not really my question, is that (require 'ruby-mode/ruby-mode) fails, even though emacs is definitely and successfully (per system call tracing) opening and reading the ruby-mode.el file. I presume this is because the provide line says just 'ruby-mode. I've found a solution for this, but if anyone can point me to any "best practices", I'd appreciate it.


(May I first say: this is the clearest question I've read here in a long time! Well done).

You can hit F4 to run your macro. That does roughly the same thing as C-x e, except it doesn't include that message!


To refine lindes' answer, I'd implement it this way:

(require 'cl) ; for flet
(add-to-list 'minor-mode-alist '(kmacro-repeat-mode " MACRO-REPEAT!"))
(defadvice kmacro-call-macro (around kmacro-call-macro-without-message activate)
  "run kmacro-call-macro without any messages"
  (flet ((message (&rest args)))
    (let ((kmacro-repeat-mode t))
      ad-do-it)))

I pulled the modification of minor-mode-alist out because there's no reason to do it multiple times. The rest is using the let and flet to do the temporary binding, which is cleaner and also safe in the presence of nonlocal exits.

Personally, I wouldn't use this advice because it disables the message function for the duration of the macro, which means all macros that actually use message would no longer function the same way. I'd probably just go with an edited version of kmacro-call-macro. Of course you could wrap the call to message with a variable that could selectively message instead.


I don't know about your "hide messages" question.

Regarding features and the require/provide functions, common practice, although I wouldn't go so far as to call it "best", is to name the .el file the same as the feature it "provides".

Not all modules do that. In those cases you need to look into the EL file to figure out the name of the feature the .el file is providing. Or check the documentation, in those rare cases where it exists. Then just use the optional arguments on the require call.

(require 'feature-name  "name-of-el-file-that-provides-feature.el")

The .el file must be on your load-path.


To disable the feature completely, you can add this to your .emacs:

(setq kmacro-call-repeat-key nil)

There is no way (currently) to keep the functionality enabled but without the message.


Well, taking the challenge of the "there's no way to do it" answer (for which I am thankful, let it be said), I set out to try and find a way to do this.

I had the thought that it would be nice to have something show up in the mode line, instead of as a message, so...

I read (some web-accessible version of) the source code for kmacro-call-macro, and the elisp Minor Mode Conventions, and various other web pages. I tried some things. I did some debugging. And finally, I came up with this (imperfect -- more on that below) bit of elisp:

;;;;; change kmacro-call-macro (C-x e) to not generate any messages,
;;;;; and instead add a minor mode to the modeline
(defadvice kmacro-call-macro (around kmacro-call-macro-without-message activate)
  "run kmacro-call-macro without any messages"
  (fset 'saved-message (symbol-function 'message))
  (unless (assq 'kmacro-repeat-mode minor-mode-alist)
    (setq minor-mode-alist
          (cons '(kmacro-repeat-mode " MACRO-REPEAT!") minor-mode-alist)))
  (setq kmacro-repeat-mode t)
  (defun message (format-string &rest args))
  ad-do-it
  (fset 'message (symbol-function 'saved-message))
  (setq kmacro-repeat-mode nil))

I'm quite certain that this is not the cleanest way to do this -- in fact, it actually seems to be somewhat buggy -- not always turning on and off the mode line message when it ought to. But it mostly works, and this makes me happy.

If anyone has any hints on how to improve it further, I would appreciate them.

I figure another solution is to re-write kmacro-call-macro to basically include this functionality, possibly with another customization variable to control it. Doing so, I imagine, would also allow for the additional information (key to repeat with; repeat-count information) that's in the message to appear. Perhaps that's even possible using defadvice? Maybe influencing the value of ad-return-value via the re-defined message function or something?

Anyway, the above code has been added to my .emacs file, and hopefully will be refined at some point, when I know my way around elisp and its best practices a bit better.

I hope someone else finds this useful.

Again, improvements to this are most welcome.

edit:

I originally had:

  (defun message (s &optional rest stuff))

which should really have been (and now is, above):

  (defun message (format-string &rest args))

Here's hoping that solves the problems! It's intermittent enough that I consider it too early to tell...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜