From a2985bb101faac9f085176e0329488b91b81dfb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Thu, 9 Nov 2017 23:29:39 +0100 Subject: [PATCH] ui: Provide hints for unbound-variable errors. * guix/ui.scm (known-variable-definition): New procedure. (report-load-error): Handle 'unbound-variable'. --- guix/ui.scm | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/guix/ui.scm b/guix/ui.scm index 02f3638f3a..9f790b6451 100644 --- a/guix/ui.scm +++ b/guix/ui.scm @@ -229,6 +229,38 @@ messages." (else #t)))))) +(define (known-variable-definition variable) + "Search among the currently loaded modules one that defines a variable named +VARIABLE and return it, or #f if none was found." + (define (modulelist (lambda (name module) + module) + (module-submodules head))))) + (match (module-local-variable head variable) + (#f (loop next suggestions)) + (_ + (match (module-name head) + (('gnu _ ...) head) ;must be that one + (_ (loop next (cons head suggestions))))))))))) + (define* (display-hint message #:optional (port (current-error-port))) "Display MESSAGE, a l10n message possibly containing Texinfo markup, to PORT." @@ -256,6 +288,16 @@ ARGS is the list of arguments received by the 'throw' handler." (let ((loc (source-properties->location properties))) (format (current-error-port) (G_ "~a: error: ~a~%") (location->string loc) message))) + (('unbound-variable proc message (variable) _ ...) + (match args + ((key . args) + (print-exception (current-error-port) frame key args))) + (match (known-variable-definition variable) + (#f + (display-hint (G_ "Did you forget a @code{use-modules} form?"))) + (module + (display-hint (format #f (G_ "Try adding @code{(use-modules ~a)}.") + (module-name module)))))) (('srfi-34 obj) (if (message-condition? obj) (if (error-location? obj)