From 3ad2680edff1c9d734d60fc3a49758c385f122c3 Mon Sep 17 00:00:00 2001 From: Josef Vlach Date: Thu, 28 May 2020 21:16:43 +0100 Subject: [PATCH] Hydra implementation --- README.md | 24 +++++++++ gdscript-godot.el | 34 ++++++++---- gdscript-hydra.el | 132 ++++++++++++++++++++++++++++++++++++++++++++++ gdscript-mode.el | 3 ++ 4 files changed, 183 insertions(+), 10 deletions(-) create mode 100644 gdscript-hydra.el diff --git a/README.md b/README.md index 06516b0..8d1fbfd 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,28 @@ Here are the available options: The last selected option is saved for the next time you call `gdscript-godot-run-project-debug`. To remove debug options, you need to call the command with the universal argument again. + +### Using Hydra + +Running `gdscript-hydra-show` (C-c r) opens [hydra](https://github.com/abo-abo/hydra) for quick launching of a project, a scene or a script. + +``` +d ( ) Debug p run current project t run current script q quit +e ( ) Editor s run current scene g switch to *godot* + +c [ ] Visible collisions shapes +n [ ] Visible navigation + +``` + +Notes: + - `( )` represents radio button toggle + - `[ ]` represents checkbox toggle + +Hydra is alternative way how to run C-c C-r * commands in combination with C-u. + +Hydra also offers quick navigation to `*godot*` buffer. + ### Formatting code with gdformat You can call the `gdscript-format` function to format the current buffer with @@ -188,6 +210,8 @@ The following shortcuts are available by default: - Browsing the code reference: - C-c C-b a `gdscript-docs-browse-api` - C-c C-b o `gdscript-docs-browse-symbol-at-point` +- Open hydra: + - C-c r `gdscript-hydra-show` (require hydra package to be installed ## Customization diff --git a/gdscript-godot.el b/gdscript-godot.el index be8fc14..134d633 100644 --- a/gdscript-godot.el +++ b/gdscript-godot.el @@ -36,6 +36,8 @@ (require 'gdscript-utils) ;;;###autoload +(defvar gdscript-godot--debug-options-hydra nil) + (defvar gdscript-godot--debug-selected-option 1) (defvar gdscript-godot--debug-options-alist @@ -44,6 +46,19 @@ (3 . "--debug-navigation") (4 . "--debug-collisions --debug-navigation"))) +(defmacro gdscript-godot--debug-options-handler (debug-options &rest body) + "Set debug-options either as set by Hydra, or use one provided by prefix argument selection." + (declare (indent 1) (debug t)) + `(let* ((debug-option-index + (if current-prefix-arg + (gdscript-godot--change-debug-options) + gdscript-godot--debug-selected-option)) + (prefix-options (cdr (assoc debug-option-index gdscript-godot--debug-options-alist))) + (use-hydra-options (not (booleanp gdscript-godot--debug-options-hydra))) ;; gdscript-godot--debug-options-hydra is a string when run from hydra + (,debug-options (if use-hydra-options gdscript-godot--debug-options-hydra prefix-options))) + ,@body + (setq gdscript-godot--debug-options-hydra nil))) + (defun gdscript-godot--run-command (cmd &optional show) "Run a Godot process. @@ -81,11 +96,7 @@ file's directory as starting point." When run with prefix argument, it offers extra debug options to choose from." (interactive) - (let* ((debug-option-index - (if current-prefix-arg - (gdscript-godot--change-debug-options) - gdscript-godot--debug-selected-option)) - (debug-options (cdr (assoc debug-option-index gdscript-godot--debug-options-alist)))) + (gdscript-godot--debug-options-handler debug-options (gdscript-godot--run-command (concat (gdscript-godot--build-shell-command) " -d " debug-options) t))) @@ -97,12 +108,15 @@ When run with prefix argument, it offers extra debug options to choose from." (gdscript-util--get-godot-project-file-path-relative buffer-file-name) ".tscn"))) (defun gdscript-godot-run-current-scene-debug () - "Run the current script file in Godot Engine." + "Run the current script file in Godot Engine. + +When run with prefix argument, it offers extra debug options to choose from." (interactive) - (gdscript-godot--run-command - (concat (gdscript-godot--build-shell-command) " -d " - (gdscript-util--get-godot-project-file-path-relative buffer-file-name) ".tscn") - t)) + (gdscript-godot--debug-options-handler debug-options + (gdscript-godot--run-command + (concat (gdscript-godot--build-shell-command) " -d " debug-options + (gdscript-util--get-godot-project-file-path-relative buffer-file-name) ".tscn") + t))) (defun gdscript-godot-edit-current-scene () "Run the current script file in Godot Engine." diff --git a/gdscript-hydra.el b/gdscript-hydra.el new file mode 100644 index 0000000..75ab969 --- /dev/null +++ b/gdscript-hydra.el @@ -0,0 +1,132 @@ +;;; gdscript-hydra.el --- Hydra for launching Godot -*- lexical-binding: t; -*- +;; +;; Copyright (C) 2020 GDQuest and contributors +;; +;; Author: Josef Vlach +;; URL: https://github.com/GDQuest/emacs-gdscript-mode/ +;; Version: 1.0.0 +;; Package-Requires: ((emacs "26.3")) +;; Maintainer: nathan@gdquest.com +;; Created: May 2020 +;; Keywords: languages +;; +;; This file is not part of GNU Emacs. +;; +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . +;; +;;; Commentary: +;; +;; Hydra for launching Godot. It offers options to launch Godot in debug mode or open editor or run the script. +;; +;; When running in debug mode it offers two additional flags to pass to Godot: +;; --debug-collisions +;; --debug-navigation +;; +;;; Code: + +(require 'hydra nil t) +(require 'gdscript-godot) + +;;;###autoload +(defvar gdscript-hydra--debug nil) +(defvar gdscript-hydra--editor nil) +(defvar gdscript-hydra--debug-collisions nil) +(defvar gdscript-hydra--debug-navigation nil) + +(defun gdscript-hydra-show () + "Show gdcript hydra." + (interactive) + (when (not (featurep 'hydra)) + (error "gdscript-hydra.el: No `hydra.el' available. To execute `gdscript-hydra-show' command you need to install hydra.el.")) + (gdscript-hydra--menu/body)) + +(defun gdscript-hydra--selected (selected) + "Visual representation for (non)selected checkboxes." + (if selected "x" " ")) + +(defun gdscript-hydra--dispatch (run-default run-debug run-editor) + "Run Godot with selected flag. + +RUN-DEFAULT is a function to call when neither debug or scene flag is selected in hydra. +RUN-DEBUG is a function to call when debug flag is selected in hydra. +RUN-EDITOR is a function to call when editor flag is selected in hydra. +" + (cond + ((and (not gdscript-hydra--debug) + (not gdscript-hydra--editor)) (funcall run-default)) + (gdscript-hydra--debug (funcall run-debug)) + (gdscript-hydra--editor (funcall run-editor)))) + +(defun gdscript-hydra--run (project-or-scene) + "Dispatcher from hydra heads to gdscript-godot-* commands. + +It is setting variable `gdscript-godot--debug-options-hydra' based on hydra checkboxes." + (setq gdscript-godot--debug-options-hydra + (concat + (when gdscript-hydra--debug-collisions "--debug-collisions ") + (when gdscript-hydra--debug-navigation "--debug-navigation "))) + + (pcase project-or-scene + (:project (gdscript-hydra--dispatch 'gdscript-godot-run-project + 'gdscript-godot-run-project-debug + 'gdscript-godot-open-project-in-editor)) + (:scene (gdscript-hydra--dispatch 'gdscript-godot-run-current-scene + 'gdscript-godot-run-current-scene-debug + 'gdscript-godot-edit-current-scene)) + (:script (gdscript-godot-run-current-script)))) + +(defun gdscript-hydra--open-godot-buffer () + "Find buffer named *godot* and if it exists open it in other window." + (let ((godot-buffer (seq-find + (lambda (current-buffer) + (with-current-buffer current-buffer + (equal (buffer-name) "*godot*"))) (buffer-list)))) + (when godot-buffer (switch-to-buffer-other-window godot-buffer)))) + +(ignore-errors + ;; Don't signal an error when hydra.el is not present + (defhydra gdscript-hydra--menu (:hint none) + " +_d_ (?d?) Debug _p_ run current project _t_ run current script _q_ quit +_e_ (?e?) Editor _s_ run current scene _g_ switch to *godot* + +_c_ [?c?] Visible collisions shapes +_n_ [?n?] Visible navigation +" + ("d" (progn + (setq gdscript-hydra--debug (not gdscript-hydra--debug) + gdscript-hydra--editor nil) + (unless gdscript-hydra--debug + (setq + gdscript-hydra--debug-collisions nil + gdscript-hydra--debug-navigation nil))) (gdscript-hydra--selected gdscript-hydra--debug)) + ("e" (setq gdscript-hydra--editor (not gdscript-hydra--editor) + gdscript-hydra--debug nil + gdscript-hydra--debug-collisions nil + gdscript-hydra--debug-navigation nil) (gdscript-hydra--selected gdscript-hydra--editor)) + ("p" (gdscript-hydra--run :project)) + ("s" (gdscript-hydra--run :scene)) + ("t" (gdscript-hydra--run :script)) + ("c" (setq gdscript-hydra--debug-collisions (not gdscript-hydra--debug-collisions) + gdscript-hydra--debug t + gdscript-hydra--editor nil) (gdscript-hydra--selected gdscript-hydra--debug-collisions)) + ("n" (setq gdscript-hydra--debug-navigation (not gdscript-hydra--debug-navigation) + gdscript-hydra--debug t + gdscript-hydra--editor nil) (gdscript-hydra--selected gdscript-hydra--debug-navigation)) + ("g" (gdscript-hydra--open-godot-buffer) :color blue) + ("q" nil))) + +(provide 'gdscript-hydra) + +;;; gdscript-hydra.el ends here diff --git a/gdscript-mode.el b/gdscript-mode.el index d7a7cfd..a529f98 100644 --- a/gdscript-mode.el +++ b/gdscript-mode.el @@ -40,6 +40,7 @@ (require 'gdscript-format) (require 'gdscript-rx) (require 'gdscript-godot) +(require 'gdscript-hydra) ;;;###autoload (add-to-list 'auto-mode-alist '("\\.gd\\'" . gdscript-mode)) @@ -75,6 +76,8 @@ ;; Docs. (define-key map (kbd "C-c C-b a") 'gdscript-docs-browse-api) (define-key map (kbd "C-c C-b o") 'gdscript-docs-browse-symbol-at-point) + ;; Hydra + (define-key map (kbd "C-c r") 'gdscript-hydra-show) map) "Keymap for `gdscript-mode'.")