Debugger - initial support

This commit is contained in:
Josef Vlach
2020-09-10 20:01:51 +01:00
parent dde7ffa735
commit 80b08e0afd
6 changed files with 1561 additions and 8 deletions

View File

@@ -231,3 +231,56 @@ Code example:
(setq gdscript-godot-executable "/path/to/godot") ;; Use this executable instead of 'godot' to open the Godot editor.
(setq gdscript-gdformat-save-and-format t) ;; Save all buffers and format them with gdformat anytime Godot executable is run.
```
## Debugger
When any breakpoint exists, running Project will automatically start debugger server (if one isn't already running) and connect to it.
Debugger server runs on `localhost` with port specified by `gdscript-debug-port` customizable variable (`9010` by default).
### Special buffers
There are four special purpose buffers containing various information.
#### * Breakpoints *
Contains list of existing breakpoints.
- Key bindings:
- <kbd>SPC</kbd> `gdscript-debug-toggle-breakpoint`
- <kbd>RET</kbd> `gdscript-debug-goto-breakpoint`
- <kbd>TAB</kbd> `gdscript-debug-display-stack-dump-buffer`
- <kbd>D</kbd> `gdscript-debug-delete-breakpoint`
`gdscript-debug-toggle-breakpoint` command will enable/disable all breakpoints.
#### * Stack dump *
Contains stack dump information.
- Key bindings:
- <kbd>SPC</kbd> `gdscript-debug-jump-to-stack-point`
- <kbd>RET</kbd> `gdscript-debug-show-stack-frame-vars`
- <kbd>TAB</kbd> `gdscript-debug-display-stack-frame-vars-buffer`
- <kbd>n</kbd> `next-line`
- <kbd>p</kbd> `previous-line`
#### * Stack frame vars *
Display locals/members/globals variables for current stack point.
Variables of type `ObjectId` can be furher inspected by pressing <kbd>RET</kbd> when point is at `Object ID: xxxx` text.
- Key bindings:
- <kbd>RET</kbd> `gdscript-debug-inspect-object-id`
- <kbd>TAB</kbd> `gdscript-debug-display-inspector-buffer`
#### * Inspector *
Display detailed information about selected `ObjectId`.
- Key bindings:
- <kbd>RET</kbd> `gdscript-debug-display-breakpoint-buffer`
### GDScript file keybinding
- Placing breakpoints:
- <kbd>C-c C-d b</kbd> `gdscript-debug-add-breakpoint`
- <kbd>C-c C-d r</kbd> `gdscript-debug-remove-breakpoint`
- When break at breakpoint:
- <kbd>C-c C-d n</kbd> `gdscript-debug-next`
- <kbd>C-c C-d c</kbd> `gdscript-debug-continue`
- <kbd>C-c C-d s</kbd> `gdscript-debug-step`

View File

@@ -139,6 +139,11 @@ directory path containing the file `index.html'."
(defcustom gdscript-docs-online-search-api-url "https://docs.godotengine.org/en/stable/search.html?q=%s&check_keywords=yes&area=default"
"Online Godot API search url"
:type 'string
:group 'gdscript)
(defcustom gdscript-debug-port 6010
"Debugger server port."
:type 'integer
:group 'gdscript)

1469
gdscript-debug.el Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -34,6 +34,7 @@
(require 'gdscript-comint)
(require 'gdscript-customization)
(require 'gdscript-debug)
(require 'gdscript-history)
(require 'gdscript-project)
(require 'gdscript-utils)
@@ -70,6 +71,17 @@ The output of the process will be provided in a buffer named
`*godot - <project-name>*'."
(let ((args (gdscript-util--flatten arguments)))
(gdscript-history--add-to-history args)
(when gdscript-debug--breakpoints
;; Start debugger server if it is not running already
(unless (get-process (gdscript-debug-process-name (gdscript-util--find-project-configuration-file)))
(gdscript-debug-make-server))
(push (mapconcat (lambda (breakpoint)
(let ((file (breakpoint->file breakpoint))
(line (breakpoint->line breakpoint)))
(format "%s:%s" file line))) gdscript-debug--breakpoints ",") args)
(push "--breakpoints" args)
(push (format "127.0.0.1:%s" gdscript-debug-port) args)
(push "--remote-debug" args))
(gdscript-comint--run (append (gdscript-godot--build-shell-command) args))
(setq gdscript-godot--debug-options-hydra :not-list)))

View File

@@ -41,6 +41,7 @@
(require 'gdscript-rx)
(require 'gdscript-godot)
(require 'gdscript-hydra)
(require 'gdscript-debug)
;;;###autoload
(add-to-list 'auto-mode-alist '("\\.gd\\'" . gdscript-mode))
@@ -79,6 +80,17 @@
(define-key map (kbd "C-c C-b s") 'gdscript-docs-online-search-api)
;; Hydra
(define-key map (kbd "C-c r") 'gdscript-hydra-show)
;; Debugger
(define-key map (kbd "C-c C-d C-d s") 'gdscript-debug-display-stack-frame-vars-buffer)
(define-key map (kbd "C-c C-d C-d d") 'gdscript-debug-display-stack-dump-buffer)
(define-key map (kbd "C-c C-d C-d b") 'gdscript-debug-display-breakpoint-buffer)
(define-key map (kbd "C-c C-d C-d i") 'gdscript-debug-display-inspector-buffer)
(define-key map (kbd "C-c C-d b") 'gdscript-debug-add-breakpoint)
(define-key map (kbd "C-c C-d r") 'gdscript-debug-remove-breakpoint)
(define-key map (kbd "C-c C-d q") 'gdscript-debug-make-server)
(define-key map (kbd "C-c C-d n") 'gdscript-debug-next)
(define-key map (kbd "C-c C-d c") 'gdscript-debug-continue)
(define-key map (kbd "C-c C-d s") 'gdscript-debug-step)
map)
"Keymap for `gdscript-mode'.")

View File

@@ -99,11 +99,12 @@ Start the search from START-PATH if provided. Otherwise, the search
starts from the current buffer path.
WARNING: the Godot project must exist for this function to work."
(let ((base-path (or start-path default-directory)))
(expand-file-name
(locate-dominating-file base-path
(lambda (parent)
(directory-files parent t "project.godot"))))))
(let* ((base-path (or start-path default-directory))
(dominating-file
(locate-dominating-file base-path
(lambda (parent)
(directory-files parent t "project.godot")))))
(when dominating-file (expand-file-name dominating-file))))
(defun gdscript-util--get-godot-project-name ()
"Retrieve the project name from Godot's configuration file."
@@ -124,9 +125,10 @@ WARNING: the Godot project must exist for this function to work."
(defun gdscript-util--get-godot-project-file-path-relative (file-path)
"Return the relative path of `FILE-PATH' to Godot's configuration file."
(concat (file-name-sans-extension
(file-relative-name file-path
(gdscript-util--find-project-configuration-file)))))
(let ((project-configuration-file (gdscript-util--find-project-configuration-file)))
(when project-configuration-file
(concat (file-name-sans-extension
(file-relative-name file-path project-configuration-file))))))
(defun gdscript-util--flatten (xs)
"Flatten deeply nested list.