0

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 is 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.

lindes
  • 9,854
  • 3
  • 33
  • 45
  • Why do you require 'ruby-mode/ruby-mode rather than just 'ruby-mode? – Brian Postow May 25 '10 at 16:25
  • Because requiring 'ruby-mode wasn't working (because ruby-mode.el is in a subdirectory called ruby-mode, as checked out from svn sources), and that was the solution I was attempting at that point. I've since changed (with some convolutions in between, that worked but were less elegant) to using `(require 'ruby-mode "ruby-mode/ruby-mode.el")`, which works fine. – lindes May 27 '10 at 02:59

5 Answers5

3

(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!

offby1
  • 6,767
  • 30
  • 45
  • can you tell me what command F-4 runs by default? I have it over-ridden to calendar, so that doesn't work for me... – Brian Postow May 25 '10 at 16:24
  • @BrianPostow Try from a fresh terminal `emacs -q` then in the Emacs, `C-h k f4`. That will show `kmacro-end-or-call-macro`. – Trey Jackson May 25 '10 at 16:36
  • Thanks! Glad it was clear. :-) And F4... yay, that works! (It's a little clunky on my Mac laptop, since the f4 key opens "Dashboard", but Fn-F4 passes F4 along to the underlying application, so it works. :-) – lindes May 26 '10 at 22:38
  • addendum: It would still be nice to be able to do this with `C-x e`... `fn F4` is much more difficult for me to type on this keyboard... (plus I just like to stay close to the home row.) – lindes May 26 '10 at 22:54
1

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.

Cheeso
  • 189,189
  • 101
  • 473
  • 713
  • Ahh, sweet! I didn't realize that optional arg was there. That totally solves that problem, thank you! – lindes May 26 '10 at 22:37
1

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.

Trey Jackson
  • 73,529
  • 11
  • 197
  • 229
  • Hmmm, no way, huh? Surely there's *some* way. :-) (If only hacking the emacs source and re-compiling from scratch... though I'm guessing it need not go that far.) Could I perhaps do something with defadvice? I'm attempting to figure that out, now, but... it's all very new territory for me. – lindes May 27 '10 at 01:30
  • @lindes Fair enough. :) Take a look at `kmacro-call-macro`, that's what you need to change. – Trey Jackson May 27 '10 at 03:32
  • Yeah... I decided to use defadvice to change its behavior, though the thought did also cross my mind of changing it itself. :-) (I've just added an answer to this question with what I came up with. Input welcome.) – lindes May 27 '10 at 06:03
1

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.

Community
  • 1
  • 1
Trey Jackson
  • 73,529
  • 11
  • 197
  • 229
  • Excellent, thanks Trey! I just changed my emacs config to use this, and it seems much happier. Yay, flet and let! – lindes May 31 '10 at 00:30
0

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...

lindes
  • 9,854
  • 3
  • 33
  • 45