Emacs - how to see/how to debug a single elisp function/emacs command - emacs

There is one thing that I don't like on table function in Org-mode for emacs. I would like to see all the functions that get executed by function that I run as Emacs command.
What is the best way to do that? Any tips how to get started with debuging elisp code, especially single command of interest?

C-hf function name to find the source code for the function.
C-uC-M-x to instrument the function for Edebug.
Whenever the function is called, Emacs will drop into Edebug which makes it easy to execute the function step by step, inspect variables, and do other typical debugging tasks. See (info "(Elisp)Edebug") for more information.

I prefer the traditional Emacs debugger to edebug. To use it:
M-x debug-on-entry the-function RET
Then, whenever the-function is invoked, the debugger is entered. Use d to step through the evaluation, and c if you want to skip through a step (not dive into its details.
It helps to view the definition of the-function in another window/frame while you step through it.
You can cancel debug-on-entry using M-x cancel-debug-on-entry.

C-h f to go to function help mode, then type the name of the function. If it is an elisp function, you can then view the source and look for yourself what functions it calls.

If you want a programmatic way to see the source of a function (akin to Clojure's source macro) you can use the symbol-function subroutine.
For instance, there is a defun do-math in my .emacs file. To see its source, I can do the following
(symbol-function 'do-math)
and it gives me
ELISP> (symbol-function 'do-math)
(lambda
(expression)
(interactive "sexpression:")
(insert
(number-to-string
(eval
(read expression)))))
See also :
https://www.gnu.org/software/emacs/manual/html_node/elisp/Function-Indirection.html
See also also :
http://ergoemacs.org/emacs/elisp_symbol.html

Related

How to extend Neotree to open a file using hexl?

I'm trying to extend Neotree to open a file using hexl-mode with the shortcut C-c C-x. How would one do this?
I've tried to evaluate a key definition after the Neotree load where it uses my/neotree-hex to open a file path using neo-buffer--get-filename-current-line.
(defun my/neotree-hex
(hexl-find-file neo-buffer--get-filename-current-line))
(with-eval-after-load 'neotree
(define-key neotree-mode-map (kbd "C-c C-x")
'my/neotree-hex))
At the very least, you are missing the (empty) argument list in the function:
(defun my/neotree-hex ()
(hexl-find-file neo-buffer--get-filename-current-line))
I don't know what neo-buffer--get-filename-current-line is: if it is a function, then you are not calling it correctly - in lisp, you call a function by enclosing the (name of the) function and its arguments in parens: (func arg1 arg2 ...)[1]; so if it is a function and it takes no arguments, then your function should probably look like this:
(defun my/neotree-hex ()
(interactive)
(hexl-find-file (neo-buffer--get-filename-current-line)))
In order to be able to bind it to a key, you have to make your function a command, which means that you need to add the (interactive) form.
Disclaimer: I know nothing about neotree.
[1] You might want to read an introduction to lisp. One (specifically tailored to Emasc Lisp) is included with the emacs documentation, but is also available online. Eventually, you will want to read the Emacs Lisp Reference Manual. Calling a function is covered in the Introduction and is covered in detail in the Reference.

SLIME on Emacs with paredit in repl - how to prevent execution of incomplete but balanced expressions?

I use paredit on emacs with SLIME's repl. This means that at any point during my typing on the repl, my s-expressions are balanced.
However, they may not be complete, and I might want to continue typing inside them in another line, as follows:
CL-USER> (defun print-hello ()
)
When I start a new line by pressing the enter key, however, the SLIME repl executes my incomplete expression. I want it to wait for me to complete the expression, as follows:
CL-USER> (defun print-hello ()
(format t "Hello, world"))
How do I make this happen please?
For that situations, when writing long s-expressions in REPL I think that the best way is to use the slime scratch buffer. you can edit it and after that execute with
C-j
No problem pressing enter inside the buffer, I'm using sly but the capture could be like this:
(defun print-hello ()
(format t "Hello, world"))
; => PRINT-HELLO
Also another alternative is working without the last parent :-(
or as suggested in a comment by #jkiisky, type the expression and add in the middle of the s expression C-j
CL-USER> (defun
)
Related to your question, lispy provides integration with SLIME.
I typically never type anything into the REPL buffer. Instead, I edit all code in place in the source file, and use e to eval the current sexp.
lispy is also a super-set of paredit, if compatibility is your concern.

Function Definition - Don't know how to find

I use SlimeNav to read elisp code. It works good mostly, but for inbuilt functions, at times, it does not work.
(local-file (file-relative-name
temp-file
(file-name-directory buffer-file-name))))
In this snippet, when i press Alt + . on local-file function, it says,
Don't know how to find 'local-file'
local-file is not a function anywhere in the core. It's used as a let-bound variable 7 times though.
Maybe you confused it.
Also remember that when accessing the documentation on a function (eg with C-h f), you should see a link you can click to get to the source code. Works also with the C sources if they are available in a way Emacs can find.
As an example, the documentation for find-file looks like this:
find-file is an interactive compiled Lisp function in `files.el'.
It is bound to <open>, C-x C-f, <menu-bar> <file> <new-file>.
(find-file FILENAME &optional WILDCARDS)
Edit file FILENAME.
...
You should be able to see that `files.el' comes out in a different colour, this you can click and it will bring you to the definition of that function.

Emacs: define custom hook on a command

Is there a way to hook onto command A, so that B is always called after A executes?
I think the most straight-forward way to accomplish this is through the use of advice.
You would do something along the lines of:
(defadvice command-A (after b-after-a activate)
"Call command-B after command-A"
(command-B))
This approach has the advantage that it works even when command-A is redefined. It does not, however, work on macros or on primitive functions called from the C code. But, in practice the thought of advising those functions is rare.
That said, it might be worth looking into just defining a new command (command-C) which first calls command-A and then command-B.
You could also play around with symbol function indirection and writing a new command.
It kind of depends on what you're trying to solve.
You can advice a function using defadvice:
;; This is the original function command-A
(defun command-A () (do-it))
;; This call will cause (do-sometihng-after-command-A) to be called
;; every-time (command-A) is called.
(defadvice command-A (after after-command-A)
(do-something-after-command-A))
;; Enable the advice defined above
(ad-activate 'command-A)
See the info node (elisp)Advising Functions for more information and examples.

Opening definition of Emacs command

is it possible to open in emacs elisp file with command definition, to see, how it is defined?
Yes you can call M-x find-function
Some functions are implemented in C. To be able to find C function you have to download C sources (if you have not yet done so) and add the following line to your .emacs
(setq find-function-C-source-directory "/path/to/c-source")
Another way:
C-h f foo RET to see the documentation for the function foo.
The documentation will tell you, on the first line, where and how the function is defined. Click the link (or hit RET with cursor on it) to the source file where the command is defined. You have to have the Lisp sources (for Lisp code) or the C sources (for C code) installed on your system in order for this to work.
You can also start from a key, without knowing what its command is: C-h k.