If you are new to Emacs, you may run into some errors, especially after you absorb elisp snippets from the Internet or elsewhere.
Don't panic. It happens. To ease your pain, in this post I will introduce some Emacs built-in features to help you solve the problems yourself.
Start Emacs Without Any Configurations
When you have some problems/errors with built-in features, the first thing you should do is to run
emacs -Q to start another Emacs instance without any configurations from your
Here is how to do it in detail if you are not familiar with the terminal:
If you use Linux/macOS, open a terminal, then type the command
If you prefer to use Emacs in a terminal or run Emacs on a server, you can append an argument
-nwto the command, that is,
emacs -Q -nw.
P.S. If you want to know more about the command line arguments, you can look it up in the
man emacsin the shell) or type
emacs --helpto see the help information, so as to get a better understanding of how to run Emacs from the command line.
Or if you use Windows, you can run the
cmdprogram first (type
Super+r cmd ENTER),
cdinto the Emacs bin directory, then type
runemacs.exe -Qto run it.
Investigate the Faulty Package Within a Clean Emacs
emacs -Q helps to debug built-in features. But when it comes to debugging third-party packages, like the ones you install from melpa, we need to do a bit more, as we need to load the package.
There are roughly two ways to load it.
For example, if we now have a problem with my ppcompile package, we can prepare a snippet (e.g. in
/tmp/try-ppcompile.el) to prepare the debugging environment:
;; you don't need this if you never change this variable (setq package-user-dir "~/.emacs.local.d/elpa") ;; init the package manager (require 'package) (package-initialize) ;; load the problematic package (require 'ppcompile)
Now open up a terminal/cmd, type
emacs -Q -l /tmp/try-ppcompile.el, and it will start a fairly clean Emacs with ppcompile loaded. From there, we can investigate further to see the problem.
Directly load from a specific directory
There are times that you can't utilize the package machinery to load the package, for example, you git-clone a package and load it from your local file system directly. In that case, you can use Emacs'
-L argument to specify the directory.
For example, type
emacs -Q -L /tmp/ppcompile/ --eval "(require 'ppcompile)" to launch a new Emacs with the package and start debugging immediately.
Note that you can specify more than one directory.
--debug-init To Debug Start-up Errors
It's not uncommon that when you update your
emacs.d, emacs errors when you run it next time.
Don't panic! Look carefully, and you will see that Emacs already tells you how to troubleshoot it. (Pay attention to the second red line on the above screenshot)
Open a terminal, type
emacs --debug-init, as Emacs tells us in the message, to start a new one. It will tell you where the error exactly comes from and the backtrace. Be patient and try to understand the problem, you will come up with a solution, hopefully! (The root cause in the screenshot is that the
a-bug-function function is not defined)
M-x toggle-debug-on-error to Enable Debugging
(In case you do not know yet, here is how to type
M-x toggle-debug-on-error on the keyboard:
ALT+x toggle-debug-on-error RETURN)
You may see something like the below when you're using Emacs:
To simulate such an error, for example, say we have a silly
welcome command as below:
(defun welcome () (interactive) (this-func-not-exist))
Now when you type
M-x welcome to invoke the command, you will see the error as in the above screenshot.
M-x toggle-debug-on-error to enable debugging, then it will bring up a new window with the backtrace when we
M-x welcome once again.
From the backtrace, we can see that the error is because the function of
this-func-not-exist does not exist, so the
welcome command fails.
Other times, you may see some unexpected message on the echo area at the bottom. You can try to play around the
debug-on-message variable to get the backtrace of where it comes from and figure it out.
For example, the below command will send out a message
welcome who? when you invoke it:
(defun welcome () (interactive) (message "welcome who?"))
Let's pretend that we now want to find out who print the nonsense message of
welcome who, and we can utilize the
debug-on-message variable to set up a regular expression, for instance,
(setq debug-on-message "welcome who").
Once there is a message that matches the regexp, Emacs will trap it into the debugger, and we will see who prints that message:
Other Debugging Helpers and Facilities
Variable ways to look up help docs:
C-h fto look up a function(
C-h fmeans to type
CTRL+h fin the keyboard)
C-h vto look up a variable
C-h kto look up a keybinding
C-h mto look up which major mode and minor modes are enabled in the current buffer
C-h lto view lossage, put it in another way, you will see the history of the invoked commands in a dedicated buffer
M-x describe-charto see the properties of the character at point, for example, its font face.
debug-on-entryfunction Emacs starts the debugger automatically when your function has an error, also refer to debug-on-entry (Programming in Emacs Lisp) - www.gnu.org.
debug-on-quitvariable refer to debug-on-quit (Programming in Emacs Lisp) - www.gnu.org
--init-directoryEmacs 29 adds a command line argument of
--init-directoryto specify a directory other than
~/.emacs.d/to run Emacs, where we can put our debugging code to do the investigation separately.