branch: elpa/geiser-kawa commit 1e15f014a955b91023b1e0a4b386b015e56e84d0 Author: spellcard199 <spellcard...@protonmail.com> Commit: spellcard199 <spellcard...@protonmail.com>
Refactor 'geiser-kawa-util--eval...' + related fixes --- elisp/geiser-kawa-devutil-complete.el | 3 +- elisp/geiser-kawa-devutil-exprtree.el | 2 +- elisp/geiser-kawa-util.el | 84 ++++++++++++++++++++++++++--------- 3 files changed, 66 insertions(+), 23 deletions(-) diff --git a/elisp/geiser-kawa-devutil-complete.el b/elisp/geiser-kawa-devutil-complete.el index cc0a773..c59de1f 100644 --- a/elisp/geiser-kawa-devutil-complete.el +++ b/elisp/geiser-kawa-devutil-complete.el @@ -196,7 +196,6 @@ members of package as returned by kawa-geiser." `kawa-devutil' is a java dependency of `kawa-geiser', itself a java dependency of `geiser-kawa'." (interactive) - (let* ((code-and-point-data (geiser-kawa-devutil-complete--code-point-from-toplevel)) (code-str (cdr (assoc "code-str" @@ -233,7 +232,7 @@ Argument CODE-STR is a string containing the code where completion must happen. It must be syntactically correct Kawa scheme. Argument CURSOR-INDEX is an integer representing where the cursor is inside `CURSOR-STR'." - (geiser-kawa-util--eval-to-res + (geiser-kawa-util--eval/result `(geiser:kawa-devutil-complete-expr-tree ,code-str ,cursor-index))) diff --git a/elisp/geiser-kawa-devutil-exprtree.el b/elisp/geiser-kawa-devutil-exprtree.el index 361f33b..9a95c43 100644 --- a/elisp/geiser-kawa-devutil-exprtree.el +++ b/elisp/geiser-kawa-devutil-exprtree.el @@ -35,7 +35,7 @@ (defun geiser-kawa-devutil-exprtree--for (code-str) "Get the Expression tree for CODE-STR." - (geiser-kawa-util--eval-to-res + (geiser-kawa-util--eval/result `(geiser:kawa-devutil-expr-tree-formatted ,code-str))) (defun geiser-kawa-devutil-exprtree--view-for (code-str) diff --git a/elisp/geiser-kawa-util.el b/elisp/geiser-kawa-util.el index 0df4200..1b5e14e 100644 --- a/elisp/geiser-kawa-util.el +++ b/elisp/geiser-kawa-util.el @@ -20,33 +20,77 @@ ;;; Code: -(defun geiser-kawa-util--eval-to-res (sexp) - "Alternative to geiser-eval--send/eval with custom behavior. -If a Throwable has been raised while running in Kawa an error is -signalled. -Argument SEXP is a sexp to evaluate in Kawa." - (let* ((question - (format "(geiser:eval (interaction-environment) %S)" - (format "%S" sexp))) - (answer (geiser-eval--send/wait question))) - (if (assoc 'error answer) - (signal 'peculiar-error - (list (string-trim - (car (split-string (geiser-eval--retort-output - answer) - "\t"))))) - ;; from: ((result "expr-tree") (output . ...)) - ;; to: "expr-tree" - (cadr (car answer))))) +(defun geiser-kawa-util--eval (sexp-or-str) + "Eval `sexp-or-str' in Kawa. +1. `sexp-or-str' is wrapped by: + (geiser:eval ...) +2. Resulting string is passed to `geiser-eval--send/wait' for + evaluation +Argument SEXP-OR-STR is code to be evaluated by the `geiser:eval' +procedure in Kawa. It can be either a `list' or a `string'." + ;; Check type of `sexp-or-str'. If type is not supported Kawa would + ;; receive `nil' as form to evaluate, which would raise a seemingly + ;; wierd error: + ;; unbound location: nil + ;; at gnu.mapping.DynamicLocation.get(DynamicLocation.java:36) + ;; ... + (let ((valid-types '(string cons)) + (sexp-or-str-type (type-of sexp-or-str))) + (when (not (member sexp-or-str-type + valid-types)) + (error + (concat "Wrong type argument: Type of `sexp-or-str' is " + (format "`%S'" sexp-or-str-type) ". " + "Valid types for `sexp-or-str' can only be: " + (format "%S" valid-types))))) + + (let* ((code-as-str (cond ((equal (type-of sexp-or-str) + 'string) + sexp-or-str) + ((equal (type-of sexp-or-str) + 'cons) + (format "%S" sexp-or-str)))) + (question (format + "(geiser:eval (interaction-environment) %S)" + code-as-str))) + (geiser-eval--send/wait question))) (defun geiser-kawa-util--retort-result (ret) - "Function that skips the reading `geiser-eval--retort-result' does. + "This function skips the reading `geiser-eval--retort-result' does. Differently from `geiser-eval--retort-result', this function doesn't have a variable binding depth limit. We use this when we need to read strings longer than what `geiser-eval--retort-result' allows. -Drawback is that `RET' must be valid elisp." +Drawback is that `RET' must be valid elisp, while +`geiser-eval--retort-result' uses an elisp implementation of a scheme +reader." (car (read-from-string (cadr (assoc 'result ret))))) +(defun geiser-kawa-util--eval/result (sexp-or-str + &optional retort-result) + "Alternative to `geiser-eval--send/result' with custom behavior. +- `sexp-or-str' is wrapped by: + (geiser:eval (interaction-environment) ...) +- An error is signalled if a Throwable has been raised while running + in Kawa. +Argument SEXP-OR-STR is code to be evaluated in Kawa. It can be either +a `list' or a `string'. +Optional argument RETORT-RESULT determines if Kawa's answer should be +read as an elisp object by `geiser-kawa-util--retort-result'." + (let ((answer (geiser-kawa-util--eval sexp-or-str))) + (if (assoc 'error answer) + (signal 'peculiar-error + (list (string-trim + (car (split-string (geiser-eval--retort-output + answer) + "\t"))))) + ;; from: ((result "<actual-result>") (output . ...)) + ;; to either: + ;; - `retort-result' is non-nil: <actual-result> + ;; - `retort-result' is nil: "<actual-result>" + (if retort-result + (geiser-kawa-util--retort-result answer) + (cadr (car answer)))))) + (defun geiser-kawa-util--repl-point-after-prompt () "If in a Kawa REPL buffer, get point after prompt." (save-excursion