bmag / emacs-purpose

Manage Windows and Buffers According to Purposes
GNU General Public License v3.0
498 stars 23 forks source link

Integrate debug with purpose #182

Closed wyuenho closed 3 years ago

wyuenho commented 3 years ago

debug supplies its own display actions to pop-to-buffer in order to reuse a window, which usually isn't what we want to do when there are multiple split windows, some of which maybe too small for a debug backtrace buffer. This PR hands the control of window picking back to purpose.

bcc32 commented 3 years ago

This change appears to have broken the d command in the debugger (continue until the next Elisp function call). I verified this by invoking the debugger and pressing d repeatedly.

With the 'debug integration excluded, I see:

Debugger entered--entering a function:
* spacemacs-buffer/refresh()
* apply(spacemacs-buffer/refresh nil)
* spacemacs/home()

But with the integration, I get an infinite loop of purpose--debug functions:

Debugger entered--entering a function:
* #f(compiled-function () #<bytecode 0x29683cd>)()
  purpose--debug(#f(compiled-function (&rest args) "Enter debugger.  \\<debugger-mode-map>`\\[debugger-continue]' returns from the debugger.\nArguments are mainly for use when this is called from the internals\nof the evaluator.\n\nYou may call with no args, or you may pass nil as the first arg and\nany other args you like.  In that case, the list of args after the\nfirst will be printed into the backtrace buffer.\n\nIf `inhibit-redisplay' is non-nil when this function is called,\nthe debugger will not be entered." (interactive nil) #<bytecode 0xee91cd>) lambda)
  apply(purpose--debug #f(compiled-function (&rest args) "Enter debugger.  \\<debugger-mode-map>`\\[debugger-continue]' returns from the debugger.\nArguments are mainly for use when this is called from the internals\nof the evaluator.\n\nYou may call with no args, or you may pass nil as the first arg and\nany other args you like.  In that case, the list of args after the\nfirst will be printed into the backtrace buffer.\n\nIf `inhibit-redisplay' is non-nil when this function is called,\nthe debugger will not be entered." (interactive nil) #<bytecode 0xee91cd>) lambda)
  debug(lambda)
* #f(compiled-function () #<bytecode 0x25ded25>)()
  purpose--debug(#f(compiled-function (&rest args) "Enter debugger.  \\<debugger-mode-map>`\\[debugger-continue]' returns from the debugger.\nArguments are mainly for use when this is called from the internals\nof the evaluator.\n\nYou may call with no args, or you may pass nil as the first arg and\nany other args you like.  In that case, the list of args after the\nfirst will be printed into the backtrace buffer.\n\nIf `inhibit-redisplay' is non-nil when this function is called,\nthe debugger will not be entered." (interactive nil) #<bytecode 0xee91cd>) lambda)
  apply(purpose--debug #f(compiled-function (&rest args) "Enter debugger.  \\<debugger-mode-map>`\\[debugger-continue]' returns from the debugger.\nArguments are mainly for use when this is called from the internals\nof the evaluator.\n\nYou may call with no args, or you may pass nil as the first arg and\nany other args you like.  In that case, the list of args after the\nfirst will be printed into the backtrace buffer.\n\nIf `inhibit-redisplay' is non-nil when this function is called,\nthe debugger will not be entered." (interactive nil) #<bytecode 0xee91cd>) lambda)
  debug(lambda)
* #f(compiled-function () #<bytecode 0x19ac269>)()
  purpose--debug(#f(compiled-function (&rest args) "Enter debugger.  \\<debugger-mode-map>`\\[debugger-continue]' returns from the debugger.\nArguments are mainly for use when this is called from the internals\nof the evaluator.\n\nYou may call with no args, or you may pass nil as the first arg and\nany other args you like.  In that case, the list of args after the\nfirst will be printed into the backtrace buffer.\n\nIf `inhibit-redisplay' is non-nil when this function is called,\nthe debugger will not be entered." (interactive nil) #<bytecode 0xee91cd>) lambda)
  apply(purpose--debug #f(compiled-function (&rest args) "Enter debugger.  \\<debugger-mode-map>`\\[debugger-continue]' returns from the debugger.\nArguments are mainly for use when this is called from the internals\nof the evaluator.\n\nYou may call with no args, or you may pass nil as the first arg and\nany other args you like.  In that case, the list of args after the\nfirst will be printed into the backtrace buffer.\n\nIf `inhibit-redisplay' is non-nil when this function is called,\nthe debugger will not be entered." (interactive nil) #<bytecode 0xee91cd>) lambda)
  debug(lambda)
* #f(compiled-function () #<bytecode 0x18da33d>)()
  purpose--debug(#f(compiled-function (&rest args) "Enter debugger.  \\<debugger-mode-map>`\\[debugger-continue]' returns from the debugger.\nArguments are mainly for use when this is called from the internals\nof the evaluator.\n\nYou may call with no args, or you may pass nil as the first arg and\nany other args you like.  In that case, the list of args after the\nfirst will be printed into the backtrace buffer.\n\nIf `inhibit-redisplay' is non-nil when this function is called,\nthe debugger will not be entered." (interactive nil) #<bytecode 0xee91cd>) debug)
* apply(purpose--debug #f(compiled-function (&rest args) "Enter debugger.  \\<debugger-mode-map>`\\[debugger-continue]' returns from the debugger.\nArguments are mainly for use when this is called from the internals\nof the evaluator.\n\nYou may call with no args, or you may pass nil as the first arg and\nany other args you like.  In that case, the list of args after the\nfirst will be printed into the backtrace buffer.\n\nIf `inhibit-redisplay' is non-nil when this function is called,\nthe debugger will not be entered." (interactive nil) #<bytecode 0xee91cd>) debug)
  debug(debug)
  debug--implement-debug-on-entry()
  apply(debug--implement-debug-on-entry nil)
  spacemacs/home()
  funcall-interactively(spacemacs/home)
  call-interactively(spacemacs/home nil nil)
  command-execute(spacemacs/home)
wyuenho commented 3 years ago

But it looks like you are debugging debug?

bmag commented 3 years ago

@bcc32 I will look into this, but please provide a bit more details how to reproduce the error - what steps exactly do I need to perform? Don't know how to translate "invoking the debugger" into actual actions, I don't think you meant M-x debug RET.

bcc32 commented 3 years ago

Ah, sorry for my unclear report.

But it looks like you are debugging debug?

No, I was trying to debug spacemacs/home in the example I pasted.

what steps exactly do I need to perform?

Try defining the following command:

(defun some-random-command ()
  (interactive)
  (message "%s" (file-remote-p "/")))

And then M-x debug-on-entry RET expand-file-name RET

When you invoke M-x some-random-command, the debugger appears. Pressing d is supposed to "step into" the file-remote-p function call, but instead it steps into the purpose--debug functions.

bmag commented 3 years ago

@bcc32 ok, I was able to repro by using beginning-of-buffer as the entry point for debugging. Should be fixed by #184. @wyuenho can you verify that the fix doesn't break any use-cases on your side?

bcc32 commented 3 years ago

Cool, #184 appears to work for me. I still see the purpose stuff show up, but it doesn't recurse, and eventually continues on to the functions called by the entry point.

bmag commented 3 years ago

I reverted this PR for now (in https://github.com/bmag/emacs-purpose/commit/06f727ec1aba07c41cfa397e8f08bca8c29d970d)