mmontone / emacs-inspector

Inspection tool for Emacs Lisp objects.
GNU General Public License v3.0
107 stars 9 forks source link

Edebug integration #6

Closed gcv closed 2 years ago

gcv commented 2 years ago

Thanks for your work on this. I plan to put the inspector to good use very soon.

Can the inspector be hooked into edebug in some way? I tried to eval (inspect-expression myvariable) while debugging a function, but it returned nil. An impressive UI here would let me hit a key and then have it prompt (with completing-read) for all bound variables and let me dig into them.

mmontone commented 2 years ago

I haven't implemented support for edebug, because I've never used it. But I'll gladly implement. Where should I look at, this? : https://www.gnu.org/software/emacs/manual/html_node/elisp/Edebug-Eval.html

mmontone commented 2 years ago

I think it would work for you if you use (inspector-inspect myvariable).

Perhaps the top-level function names and semantic is a bit confusing in their current form.

mmontone commented 2 years ago

An impressive UI here would let me hit a key and then have it prompt (with completing-read) for all bound variables and let me dig into them.

Good idea. I'll try to implement in the future.

gcv commented 2 years ago

I tried (inspector-inspect myvariable), it returned nil.

Here's a crash course in using edebug.

Sample function:

(defun f1 ()
  (let ((myht (make-hash-table :test #'equal)))
    (puthash :one 1 myht)
    (puthash :two 2 myht)
    myht))
  1. Put your cursor somewhere on the function body and hit C-u C-M-x. You should see Edebug: f1 flash in the message area.
  2. Call (f1).
  3. You should see highlighting for the first line in the function. Press n to step forward until both values have been added to the hash table.
  4. Press e. This turns on eval mode. You can usually look at variables here. Specifically, myht works. But (inspector-inspect myht) does not. (Emacs 27.2 here in case it's relevant.)

It's worth noting that calling (inspect-expression myht) in the function body does work, but it's a bit awkward to use because I can't pause execution. Still useful, of course.

Also, yes: a package named inspector that provides interface functions prefixed both inspect- and inspector- is confusing. It's easier to understand what's going on when the package name matches the namespace prefix.

mmontone commented 2 years ago

Thanks for your explanation. I see how I can implement an api to edebug now.

M-x eval-expression RET (inspector-inspect (edebug-eval 'myht)) RET is working.

mmontone commented 2 years ago

I've added inspect-edebug-expression command. You can enter the variable name, say myht, and you get the inspector on it.

I couldn't figure out how to provide completion; could not figure out how to access local variable names and values of edebug context.

This is unreleased for now..

gcv commented 2 years ago

Cool! Is inspect-edebug-expression added to the edebug keymap?

mmontone commented 2 years ago

Cool! Is inspect-edebug-expression added to the edebug keymap?

Nope. There's a discussion somewhere about that packages should not add/change key-bindings. But I'm doing it already for debug-mode, so ...

What do you think would be a good keybinding for edebug ? (you know the mode better than me).

mmontone commented 2 years ago

About keybindings ... I wonder if there's some common practice to apply, like provide some sensible key bindings, easy to install, with the package, but not enforce them. Like only install them if the package is required/loaded/initialized in a certain way.

gcv commented 2 years ago

Good point! The right thing is to document the procedure for adding a key binding in the README. In my packages, I try to include snippets of plain and use-package code with good defaults in the README.

As for which key to recommend for the documentation: lowercase i is taken, but I think uppercase I is available.

mmontone commented 2 years ago

I'm adding C-c C-i as key binding, because I is already taken in edebug-mode-map.

I'm setting key bindings only if they are not already defined. I think that's fair. So, you get the package default keybinding without having to go through a README.

Like this:

(when (not (keymap-lookup edebug-mode-map "C-c C-i"))
  (keymap-set edebug-mode-map "C-c C-i" #'inspect-edebug-expression))
mmontone commented 2 years ago

I'm adding C-c C-i as key binding, because I is already taken in edebug-mode-map.

I'm setting key bindings only if they are not already defined. I think that's fair. So, you get the package default keybinding without having to go through a README.

Like this:

(when (not (keymap-lookup edebug-mode-map "C-c C-i"))
  (keymap-set edebug-mode-map "C-c C-i" #'inspect-edebug-expression))

Perhaps not such a good idea because there can be other keymaps active, and bindings would be "overwritten" dynamically when edebug-mode is active. Also I've just realized C-c C-i is actually interpreted as C-c TAB, and that's usually bound to a completion command.

mmontone commented 2 years ago

@gcv Please let me know if you have any thoughts about this

gcv commented 2 years ago

The more I think about it, the less I like the idea of modifying edebug-mode-map. There's no clean way to clean up the changes, so they probably should not be made. I should have thought twice before asking you to do it. Sorry.

I think the right thing is to document what to do in the README. I looked at edebug-mode-map, it's crowded. What about suggesting M-i as the key binding?

By the way, what is keymap-set? I don't see it in Emacs 27; is it an Emacs 28/29 thing?

mmontone commented 2 years ago

The more I think about it, the less I like the idea of modifying edebug-mode-map. There's no clean way to clean up the changes, so they probably should not be made. I should have thought twice before asking you to do it. Sorry.

I think the right thing is to document what to do in the README. I looked at edebug-mode-map, it's crowded. What about suggesting M-i as the key binding?

I think I'll try with M-i, and perhaps renounce to changing any mode-maps and just document in README later.

By the way, what is keymap-set? I don't see it in Emacs 27; is it an Emacs 28/29 thing?

Oh. Must be. I saw that define-key was deprecated in the docstring, but didn't think it was for Emacs >= 28. "This is a legacy function; see ‘keymap-set’ for the recommended function to use instead."

I'll revert that because I want inspector to be able to be used with 27. Interesting problem that of deprecations ...

mmontone commented 2 years ago

I'm compiling with Emacs 27 now and realize that specifying mode in interactive is a >= 28 feature too.

https://lars.ingebrigtsen.no/2021/02/16/command-discovery-in-emacs/

That's a nice feature, but I'll wait til I switch package to >= Emacs 28.

mmontone commented 2 years ago

Something I'm realizing now .. When buffers enters edebug mode, the buffer is set to readonly. And so there are lots of keybindings that don't work anymore, as they run commands that want to insert something into the buffer. So, in a way, it is "safe" to overwrite those bindings like C-i, because those wouldn't work anyway.

mmontone commented 2 years ago

I've just set it back to C-c C-i because edebug-mode has some similar bindings and I consider it mostly harmless because buffer is readonly.

gcv commented 2 years ago

Looks great! Very excited to have this feature in the world of Emacs development.