Debug efficiently in Emacs
Please note:
- I use javascript as a use case. The solution is generic enough to be applied to any language. At the end of the article, Emacs Lisp is used as another example.
- I'm good at most debuggers. The point of this article is to deal with more difficult issues the debugger can not handle.
- My code quality is fine. It handles all the corner cases I've met. For example, single quote and double quotes will be escaped properly.
Problem
As a freelancer I am often required to debug legacy javascript code from some huge "enterprise"" applications.
The only way to debug such application is to insert as many as possible logging code, watch the output, and think.
So my problem is how to insert logging code as quickly as possible.
Solution
My solution is Yasnippet. Yasnippet allow me to insert executable Emacs Lisp code in its snippet. I will Sotake full advantage of that feature.
Logging simple JS variable
Given a variable name like "var1", I need insert javascript code as below:
console.log("var1=", var1)
Snippet: https://github.com/redguardtoo/emacs.d/blob/master/snippets/js-mode/logobject.yasnippet
This snippet need you input variable name once.
Logging complex JS variable
In real world, the JS variable is often a string like "MyController.servicea.find('.class').attr1" which I hate to type.
So the solution is that I copy the JS variable into kill ring where my snippet will read the variable name.
Snippet: https://github.com/redguardtoo/emacs.d/blob/master/snippets/js-mode/log-recent-kill-ring.yasnippet
Logging JS function name when it's called
In below example, I need insert "console.log('hello is called');" in function "hello":
function hello() {
console.log('hello is called');
}
Snippet: https://github.com/redguardtoo/emacs.d/blob/master/snippets/js-mode/log-which-function.yasnippet
This snippet use the Emacs command `which-function`. If you read the code of `which-function`, you will find that it's Imenu-mode who actually extracts the function name. But Imenu-mode requires you pre-define enough regular expressions.
Please check https://github.com/redguardtoo/emacs.d/blob/master/lisp/init-javascript.el. I have defined many regular expressions for AngularJS and JQuery.
The regular expressions could be used in both js-mode and js2-mode.
Logging JS function name with its parameters
JS example:
function hello(v1, v2,
v3, v4) {
console.log("v1=", v1, "v2=", v2, "v3=", v3, "v4=", v4);
}
I copy the parameter of JS function named "hello". It's just the content between "hello(" and ")", then Emacs Lisp code embedded in the snippet will parse and output the right content from kill ring.
BTW, since I use Evil, copy the parameter into kill-ring is as simple as pressing "yi(".
Insert JS debugger statement
@cjk provided this tip. The debugger like Firebug will pause at the debugger statement. It saves me the time to locate JS file, to go to the specific line and set breakpoint after re-deploying the application.
Snippets: https://github.com/redguardtoo/emacs.d/blob/master/snippets/js-mode/debugger.yasnippet
Bonus
Similar snippets for Emacs Lisp are defined HERE.