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

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.

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

Related

Can somebody give me a quick rundown on what the "#f()" syntax in Emacs-Lisp is doing?

Today, as I was once again traipsing through the Emacs Manual, I got a little tired and decided to pop into the Org Mode manual for something a little lighter, and I was reading about link handling, and ended up reading (and rereading) the Help documentation for 'org-file-apps.
Well, when I peeked at the related variable 'org-file-apps-windowsnt, I was surprised to see some syntax in its value that I didn't recognise.
To be clear, I've read the elisp manual virtually cover-to-cover, so while it's not uncommon for me to not feel comfortable with a particular bit of syntax, it's fairly rare these days that I don't recognise it at all.
The syntax in question is in the following expression
((remote . emacs)
(system . #f(compiled-function
(file path)
#<bytecode -0x47e8150df949387>))
(t . #f(compiled-function
(file path)
#<bytecode -0x47e8150df949387>)))
Specifically, the #f() syntax.
I tried searching across my Info manuals in Emacs, but only came up with entries related to colour values (e.g., #FFFFFF for white), next I tried DDG and Google, but since all generalised search engines have decided that even something quoted is subject to fuzziness, I haven't turned up anything there.
So, yeah, I'm just hoping somebody can explain the #f() syntax in this bit of Emacs-Lisp code, and what it's doing, and maybe why it's used. I assume it must have something to do with the use of compiled bytecode, but beyond that I'm stumped.
Apologies for what is no doubt a basic question that I've simply forgotten from reading the elisp manual, but searching, including that manual, is getting me nowhere.
I submitted Emacs bug #55853 for this, asking that the f#(...) syntax be documented.
The bug was closed as "fixed" with this explanation. Apparently this is not Lisp-readable syntax but is instead intended to be for human consumption as "pretty-printed" output. I leave it to you whether you think it serves that purpose well. This is the bug-closure explanation:
It's from:
(cl-defmethod cl-print-object ((object compiled-function) stream)
(unless stream (setq stream standard-output))
;; We use "#f(...)" rather than "#<...>" so that pp.el gives better results.
(princ "#f(compiled-function " stream)
I.e., it's from the "pretty" version of prin1, and is not meant to be
readable by the Lisp reader.
[Emacs maintainer Lars has] now mentioned this in the Special Read Syntax node in the lispref [he means the Elisp]
manual in Emacs 28.2.
In other words, this is apparently "special read syntax", i.e., Lisp reader syntax that's not readable by the Lisp reader but is meant to communicate something to humans.
That description "explains the syntax" - the idea behind it. But it doesn't really tell you what the syntax is supposed to communicate to users, i.e., how to read it as a human.
I'd guess it's trying to be a placeholder, in this case, for a (compiled) function that takes arguments FILE and PATH.
What the source code for the function is; what the function does (e.g., it's doc); or where it's defined -- nothing like that is conveyed in the "pretty"-print. And whether "compiled" there means byte-compiled or "native"-compiled also isn't made clear.
Hopefully someone else may be able to add more light with another answer here. And perhaps the 18.2 doc will make things more clear.

How to find a bug in ".emacs" or "init.el"?

Sometimes when I open Emacs, Emacs initialization fail.
That is because .emacs or init.el files have a bug. (My bugs often come from just mistyping.)
I want to find the bug in .emacs or init.el. Is there any way to do this?
To find out what part of your init file (~/.emacs) is causing the behavior you see, bisect your init file recursively: First comment-out half, to see which half is responsible, then 3/4, to see which quarter is responsible,...
To comment out a region of text (e.g. succession of lines that you have selected), I recommend comment-region (which I bind to C-x C-;). With a numeric prefix arg it uses that many ; comment chars. With a plain prefix arg (C-u) it uncomments the region instead of commenting it.
You can also start Emacs with the command-line switch --debug-init. This will cause the debugger to open when an error is raised during Emacs startup, including while your init file is loaded. The debugger backtrace tells you which evaluation raised the error (which function was called), and it shows you which function called the function where the error was raised, which function called that one, and so on.
When you know which function is the problem, if you need to you can debug its evaluation by putting (debug-on-entry 'THE-FUNCTION) near the start of your init file. That will open the debugger when the function is entered instead of just showing what happened when the error was raised. You can then step through the debugger using d (or c to skip through a step), to see just what went wrong.
If you prefer to step through the function starting at some breakpoint, then copy the source code that defines the function to your init file, and insert (debug) at the position where you want the debugger to open.
As always, the Emacs manuals are your friends. See, for instance, node Checklist in the Emacs manual and node Invoking the Debugger in the Elisp manual.
There is another debugger also, called edebug, which is also documented in the manuals. Some people prefer it to debug. (I prefer debug.) Both are good.
Using the debugger is generally more informative if you have loaded Emacs Lisp source files rather than their byte-compiled versions. If you start investigating a particular problem using the debugger, you might want to first load the *.el (not *.elc) file(s) in question.
I've had great success with elisp bug hunter https://github.com/Malabarba/elisp-bug-hunter.
The most common problems are unmatched parenthesis, loading-failed packages.:
Automated error hunting
If your Emacs init file signals an error during startup, but you don’t
know why, simply issue
M-x bug-hunter-init-file RET e
and The Bug Hunter will find it for you. Note that your init.el (or
.emacs) must be idempotent for this to work.
Interactive hunt
If Emacs starts up without errors but something is not working as it
should, invoke the same command, but choose the interactive option:
M-x bug-hunter-init-file RET i
The Bug Hunter will start a separate Emacs instance several times, and
then it will ask you each time whether that instance presented the
problem you have. After doing this about 5–12 times, you’ll be given
the results.
You can debug your .emacs file like this: Debugging a customization file
Start Emacs with the ‘-debug-init’ command-line option. This enables
the Emacs Lisp debugger before evaluating your .emacs file, and places
you in the debugger if something goes wrong. The top line in the
trace-back buffer will be the error message, and the second or third
line of that buffer will display the Lisp code from your .emacs file
that caused the problem.
You can also evaluate an individual function or argument to a function
in your .emacs file by moving the cursor to the end of the function or
argument and typing C-x C-e (M-x eval-last-sexp).
Use C-h v (M-x describe-variable) to check the value of variables
which you are trying to set or use.
I'll add it's good to anticipate. The function below, coming from oremacs.com allows to check the validity of our init file (or any other file) without starting up emacs:
(defun ora-test-emacs ()
(interactive)
(require 'async)
(async-start
(lambda () (shell-command-to-string
"emacs --batch --eval \"
(condition-case e
(progn
(load \\\"~/.emacs\\\")
(message \\\"-OK-\\\"))
(error
(message \\\"ERROR!\\\")
(signal (car e) (cdr e))))\""))
`(lambda (output)
(if (string-match "-OK-" output)
(when ,(called-interactively-p 'any)
(message "All is well"))
(switch-to-buffer-other-window "*startup error*")
(delete-region (point-min) (point-max))
(insert output)
(search-backward "ERROR!")))))
One can even add a Travis CI test.
ps: solutions summed up on wikemacs.
Some good advice has already been given. In particular, I think #Drew's response pretty much covers what you need to do.
I wanted to also mention that how you structure your config file can also help in tracking down problems. For example, grouping similar or related configuration options together can be very helpful.
However, the one thing which I found to be the most helpful was to break up my configuration into separate files. Essentially, my init.el file does nothing but setup some load-path settings so that my actual configuration code can be found and then just calls '''require to load each of the files.
In my .emacs.d directory, I have a directory called lisp and in that directory, I have a bunch of *.el files with names like init-org.el, init-clojure.el, init-javascript.el etc. In each of those files, I have the config settings relevant to the name i.e. org setup stuff in init-org.el, javascript stuff in init-javascript.el etc.
Each of these files ends with a 'provide' form i.e.
(provide 'init-org)
at the end of init-org.el and
(provide 'init-javascript)
at the end of init-javascript.el etc.
In my init.el file, I just have lines like
(add-to-list 'load-path (expand-file-name "lisp" user-emacs-directory))
(require 'init-org)
(require 'init-javascript)
(require 'init-clojre)
The benefit of doing this is that it is now even easier to bisect my init file. I can just comment out the first half of the require statements - many fewer lines.
the other benefit is that sometimes, if I'm having problems with some config, but it isn't really related to the work I need to do now, I can just comment out that require and get back to work. For example, if I am doing some clojure coding, but having some error when starting emacs due to a problem in my javascript setup, then I can just comment out the (require 'init-javascript) line and I'm good to go.

Preferring one function when a keybinding in two emacs packages overlap

On OS X, with a .emacs containing only the lines:
(require 'dired)
(add-hook 'dired-load-hook
(function (lambda ()
(load "dired-x"))))
dired-omit-mode in dired-x and ns-open-file-using-panel in ns-win fight over the keybinding M-o.
I understand the .emacs above as specifying that dired-x should be loaded just after dired—and hence the binding of M-o in dired-x should take over when emacs starts. This is not the case. For some reason the binding in ns-win wins.
How can I force the dired-x keybinding at startup?
Edit
(Following phils' suggestion)
If my .emacs also loads the two other packages that define M-o
(require 'ns-win)
(require 'facemenu)
(require 'dired)
(add-hook 'dired-load-hook
(function (lambda ()
(load "dired-x"))))
even though dired is loaded last, the binding in facemenu still takes over.
First, load ns-win, so that it sets its binding.
Then this:
(add-hook
'dired-mode-hook
(lambda()
(require 'dired-x)
(define-key dired-mode-map (kbd "M-o") 'dired-omit-mode)))
The dired-mode-hook will override anything that was previously
bound to M-o for dired-mode.
Edit: Ah, sorry, my answer wasn't relevant.
Firstly dired-x adds its bindings to the major mode map (dired-mode-map) and all minor mode maps take precedence over the major mode map.
Secondly, my assumption that your ns-win was using a minor mode may also be invalid. I really should have told you to link to that in the first place (you should always link to non-standard libraries).
Google suggests that its using the global keymap in which case it should never be overriding the dired map, but also that it's using super rather than meta as its modifier key, so I'm not at all sure I'm looking at the version you're using.
If your ns-win does provide a minor mode then the simplest option is probably to clobber the minor mode's binding with a custom function which checks the major mode and then either calls the original function or the dired-x function as appropriate.
You might use the Emacs key binding fallback approach to minimise the number of assumptions. Your test would be (eq major-mode 'dired-mode).
Original answer; not actually relevant to the question:
Minor mode map precedence is controlled by the order of the entries in minor-mode-map-alist, and that depends on the order in which libraries are loaded. The most recently loaded mode has the highest precedence (new entries are added at the front of the list).
See https://stackoverflow.com/a/5340797/324105 for one example of manipulating this alist in order to give a specific mode precedence (in your case you would likely want to use eval-after-load to perform the test, as it's a one-off).
Alternatively, you can just forcibly load/require both libraries in the desired sequence. Emacs takes fractionally longer to start up, but you don't need to worry about messing with the alist.
I'd just suggest using whichever approach you're comfortable with.

Reload Clojure files in emacs

I am just starting out learning Clojure and Emacs. I have got Clojure Box for windows running and I would like to be able to write code in a buffer then run it in the REPL without haveing to call
(use 'example.code)
all the time. I know about C-c C-k but it doesn't reload the namespace. If i use
(in-ns 'example.code)
to change namespace in the repl it works. What is the right way to do this?
in-ns is one of the right ways.
The way which feels most "right" to me is to (require '[example.code :as ec]) and work in the user namespace at the REPL; that way my throwaway experimental state stays in user and ec/foo is convenient enough to me (and it makes it obvious where foo is supposed to come from). You can always say (require :reload-all 'example.code) (same works with use) to force recompilation.
Also, here's a function to remove (from the current namespace) all mappings pulled in from a given namespace with use:
(defn unuse [ns]
(doseq [[n v] (ns-refers *ns*)]
(if (= (.. v ns name) ns)
(ns-unmap *ns* n))))
On top of that you could build
(defn reuse [ns]
(unuse ns)
(remove-ns ns)
(use :reload-all ns))
and say (reuse 'example.code) to get something close to a fresh start with your namespace. (Note that 1.2 new features such as deftype & defrecord introduce some complexities... In particular, unuse has no effect on imported class -- this includes records and deftype-created types. :reload-all still causes the deftype et al. forms to be recompiled, but I remember hitting weird cases where this didn't seem to be enough... Possibly my error, possibly some arcane aspect of these features I haven't yet fully explored.)
Maybe the "dirty" way is simply switch to the namespace of the buffer in the repl with (ns 'example.code) . Dirty cause you mix the buffer definitions with repl ones. I think the Marczyk answer is the right one.

Wrapping a quoted function in emacs-lisp

I use the cscope emacs extension (and find it quite useful). Unfortunately, it's default behaviour of only searching the current directory and below is insufficient for me, so I use the cscope-set-initial-directory to the directory of my choice. Unfortunately this has become insufficient for me as well because I have multiple different projects each with their own "initial" directory.
I have set up hot keys for the three cscope methods I use the most in emacs
(global-set-key [f9] 'cscope-find-this-text-string)
(global-set-key [f8] 'cscope-find-global-definition)
(global-set-key [f7] 'cscope-find-this-symbol)
I figured it would be pretty easy to somehow wrap those calls with a function to run cscope-set-initial-directory on a given path (generated by looking at what the buffer-file-name is). But I have as-yet been unsuccessful!
(global-set-key [f9] (lambda () (interactive) (cscope-set-initial-directory "blah") 'cscope-find-this-text-string))
doesn't work. I've also tried adding hooks to the two cscope-hooks, but neither of those seem to ever get called during my normal usage patterns. I wouldn't even mind running it once every time I switch buffers, but I didn't see a hook for that anywhere either :/.
Can someone help? :)
Disclaimer: I've not installed cscope so cannot test this.
(global-set-key (kbd "<f9>") 'my-cscope-find-this-text-string)
(defun my-cscope-find-this-text-string (dir)
(interactive "DRoot area to start search:")
(let ((default-directory dir))
(call-interactively 'cscope-find-this-text-string)))
The basic idea being you want to prompt for a directory to start from: that's the call to interactive. Then you set the directory: the let statement does that for you. Then you call the original routine you wanted, and by calling it with 'call-interactively you get prompted.
You'd wrap the other two routines similarly.
Once that's working for you, you can get fancier by customizing prompt for a root area to have its own history variable that's shared across the three routines.
Regarding your initial solution, that was a good try. Most don't realize the need for 'interactive to turn the function into a command. The reason the quoted name doesn't work for you is that the quote simply tells the interpreter to treat the symbol as a symbol and not do to anything with it. To call the routine, you'd generally do:
(lambda ()
(c-scope-find-this-text-string "some-string"))
Unfortunately, with a direct call like the one just above, you have to provide an argument (the string to search for). So, you can either add some code to prompt for the string, or use the command's built-in code to do the prompting. That's what the 'call-interactively is used for, it calls the command and invokes its 'interactive form which does the prompting.
Also, it's generally a good idea to bind keystrokes to names of commands, as opposed to bare lambdas, for two reasons: first, if you ever do C-h k (M-x describe-key), you get a meaningful command name, and second, if/when you modify the function, you can do so without having to muck with the binding as well.

Resources