diff options
| -rw-r--r-- | doc/geiser.texi | 6 | ||||
| -rw-r--r-- | doc/install.texi | 6 | ||||
| -rw-r--r-- | doc/macros.texi | 12 | ||||
| -rw-r--r-- | doc/parens.texi | 2 | ||||
| -rw-r--r-- | doc/repl.texi | 12 | ||||
| -rw-r--r-- | doc/thanks.texi | 4 | ||||
| -rw-r--r-- | elisp/geiser-base.el | 5 | ||||
| -rw-r--r-- | elisp/geiser-capf.el | 19 | ||||
| -rw-r--r-- | elisp/geiser-connection.el | 39 | ||||
| -rw-r--r-- | elisp/geiser-doc.el | 8 | ||||
| -rw-r--r-- | elisp/geiser-edit.el | 60 | ||||
| -rw-r--r-- | elisp/geiser-eval.el | 8 | ||||
| -rw-r--r-- | elisp/geiser-impl.el | 8 | ||||
| -rw-r--r-- | elisp/geiser-mode.el | 15 | ||||
| -rw-r--r-- | elisp/geiser-repl.el | 127 | ||||
| -rw-r--r-- | elisp/geiser-syntax.el | 7 | ||||
| -rw-r--r-- | elisp/geiser.el | 4 | ||||
| -rw-r--r-- | news.org | 26 | ||||
| -rw-r--r-- | readme.org | 33 |
19 files changed, 274 insertions, 127 deletions
diff --git a/doc/geiser.texi b/doc/geiser.texi index 29166d8..ea27717 100644 --- a/doc/geiser.texi +++ b/doc/geiser.texi @@ -8,7 +8,7 @@ @copying This manual documents Geiser, an Emacs environment to hack in Scheme. -Copyright @copyright{} 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2018, 2020, 2021 Jose Antonio Ortega Ruiz +Copyright @copyright{} 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2018, 2020, 2021, 2026 Jose Antonio Ortega Ruiz @quotation Permission is granted to copy, distribute and/or modify this document @@ -103,8 +103,8 @@ Cheat sheet @html <br/> <div class="navigation" align="right"> -<a class="navlink" href="https://gitlab.com/groups/emacs-geiser/-/issues">Bugs</a> -<a class="navlink" href="https://gitlab.com/emacs-geiser">Source</a> +<a class="navlink" href="https://codeberg.org/org/geiser/issues">Bugs</a> +<a class="navlink" href="https://codeberg.org/geiser">Source</a> <a class="navlink" href="http://lists.nongnu.org/mailman/listinfo/geiser-users">Mailing list</a> </div> @end html diff --git a/doc/install.texi b/doc/install.texi index b6eb030..0675af9 100644 --- a/doc/install.texi +++ b/doc/install.texi @@ -19,16 +19,16 @@ recent Emacs snapshot) and at least one of the supported Schemes, namely: @itemize @bullet +@gsupimpl{GNU Kawa, http://www.gnu.org/software/kawa/index.html, 3.1, kawa} +@gsupimpl{Gauche, http://practical-scheme.net/gauche/, 0.9.6, gauche} +@gsupimpl{Stklos, https://stklos.net/, 1.50, stklos} @supimpl{Chez, http://www.scheme.com, 9.4,chez} @supimpl{Chibi, http://synthcode.com/scheme/chibi, 0.7.3,chibi} @supimpl{Chicken, http://call-cc.org, 4.8.0, chicken} @supimpl{Gambit, http://gambitscheme.org/wiki/index.php/Main_Page, 4.9.3, gambit} -@supimpl{Gauche, http://practical-scheme.net/gauche/, 0.9.6, gauche} @supimpl{Guile, http://www.gnu.org/software/guile, 2.2, guile} -@supimpl{GNU Kawa, http://www.gnu.org/software/kawa/index.html, 3.1, kawa} @supimpl{MIT/GNU Scheme, https://www.gnu.org/software/mit-scheme, 9.0, mit} @supimpl{Racket, http://www.racket-lang.org, 7.0, racket} -@supimpl{Stklos, https://stklos.net/, 1.50, stklos} @end itemize Since Geiser supports multiple REPLs, having all of them will just add diff --git a/doc/macros.texi b/doc/macros.texi index c218dff..b1f99cd 100644 --- a/doc/macros.texi +++ b/doc/macros.texi @@ -1,11 +1,17 @@ -@set VERSION 0.20 +@set VERSION 0.33 @set VERSION_NICK -@set RELEASE_DATE December 2021 -@set EMACS_VERSION 24.4 +@set RELEASE_DATE May 2025 +@set EMACS_VERSION 27.1 +@set CODEBERG https://codeberg.org/geiser/ @set GITLAB https://gitlab.com/emacs-geiser/ @macro supimpl{NAME,URL,VERS,NM} @item +@uref{\URL\, \NAME\} \VERS\ or better, via @uref{@value{CODEBERG}\NM\, geiser-\NM\} +@end macro + +@macro gsupimpl{NAME,URL,VERS,NM} +@item @uref{\URL\, \NAME\} \VERS\ or better, via @uref{@value{GITLAB}\NM\, geiser-\NM\} @end macro diff --git a/doc/parens.texi b/doc/parens.texi index 82c2e2c..b4c6319 100644 --- a/doc/parens.texi +++ b/doc/parens.texi @@ -99,7 +99,7 @@ for you to first call @code{geiser} (or @ref{choosing-impl,,one of its variants}), @end ifhtml @ifnothtml -(or one of its variants, e.g. @code{run-guile}), +(or one of its variants, e.g. @code{geiser-guile}), @end ifnothtml and then open some Scheme files; but there's nothing wrong in first opening a couple Scheme buffers and diff --git a/doc/repl.texi b/doc/repl.texi index 01a0a18..a522a82 100644 --- a/doc/repl.texi +++ b/doc/repl.texi @@ -382,12 +382,12 @@ some related tips. Instead of using the generic @command{geiser} command, you can directly start your Scheme of choice using any of the following commands: @itemize @bullet -@item @command{run-racket} -@item @command{run-guile} -@item @command{run-chicken} -@item @command{run-mit} -@item @command{run-chibi} -@item @command{run-chez} +@item @command{geiser-racket} +@item @command{geiser-guile} +@item @command{geiser-chicken} +@item @command{geiser-mit} +@item @command{geiser-chibi} +@item @command{geiser-chez} @end itemize @anchor{active-implementations} In addition, the variable @code{geiser-active-implementations} contains a list of those diff --git a/doc/thanks.texi b/doc/thanks.texi index 14eae9b..856afad 100644 --- a/doc/thanks.texi +++ b/doc/thanks.texi @@ -78,8 +78,8 @@ gmane.lisp.scheme.geiser}. @item @cindex bug tracker You can submit bug reports either to the mailing list or to -@uref{https://gitlab.com/groups/emacs-geiser/-/issues, our bug tracker} over at -Gitlab. +@uref{https://codeberg.org/org/geiser/issues, our bug tracker} over at +Codeberg. @item @cindex IRC channel The Freenode IRC channel @i{#geiser} is the Geiserati's meeting point in diff --git a/elisp/geiser-base.el b/elisp/geiser-base.el index 4194da5..71aa8b4 100644 --- a/elisp/geiser-base.el +++ b/elisp/geiser-base.el @@ -41,9 +41,14 @@ ;;; Utilities: +(require 'ansi-color) + (defsubst geiser--chomp (str) (if (string-match-p ".*\n$" str) (substring str 0 -1) str)) +(defsubst geiser--strip-ansi (s) + (replace-regexp-in-string "" "" (ansi-color-filter-apply s))) + (defun geiser--shorten-str (str len &optional sep) (let ((str-len (length str))) (if (<= str-len len) diff --git a/elisp/geiser-capf.el b/elisp/geiser-capf.el index a3c47a3..e7c1139 100644 --- a/elisp/geiser-capf.el +++ b/elisp/geiser-capf.el @@ -1,6 +1,6 @@ ;;; geiser-capf.el --- Setup for Geiser's CAPFs -*- lexical-binding: t; -*- -;; Copyright (c) 2022 Jose Antonio Ortega Ruiz +;; Copyright (c) 2022, 2025 Jose Antonio Ortega Ruiz ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the Modified BSD License. You should @@ -18,6 +18,7 @@ (require 'geiser-doc) (require 'geiser-completion) (require 'geiser-edit) +(require 'geiser-syntax) (defun geiser-capf--company-docsig (id) (condition-case err @@ -38,13 +39,15 @@ (current-buffer)))))) (defun geiser-capf--company-location (id) - (condition-case _err - (when (and geiser-impl--implementation (not (geiser-autodoc--inhibit))) - (let ((id (make-symbol id))) - (condition-case nil - (geiser-edit-module id 'noselect) - (error (geiser-edit-symbol id 'noselect))))) - (error (message "Location not found for %s" id)))) + (ignore-errors + (when (and geiser-impl--implementation (not (geiser-autodoc--inhibit))) + (let ((id (if (stringp id) (geiser-syntax--form-from-string id) id))) + (if-let* ((mloc (geiser-edit-module-location id)) + (f (geiser-edit--location-file mloc))) + (cons f 1) + (if-let* ((sloc (geiser-edit-symbol-location id)) + (f (geiser-edit--location-file sloc))) + (cons f (or (geiser-edit--location-line sloc) 1)))))))) (defun geiser-capf--thing-at-point (module &optional _predicate) (with-syntax-table scheme-mode-syntax-table diff --git a/elisp/geiser-connection.el b/elisp/geiser-connection.el index af185b4..414cc6b 100644 --- a/elisp/geiser-connection.el +++ b/elisp/geiser-connection.el @@ -1,6 +1,6 @@ ;;; geiser-connection.el --- Talking to a scheme process -*- lexical-binding: t; -*- -;; Copyright (C) 2009-2011, 2013, 2021-2022 Jose Antonio Ortega Ruiz +;; Copyright (C) 2009-2011, 2013, 2021-2022, 2025, 2026 Jose Antonio Ortega Ruiz ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the Modified BSD License. You should @@ -39,7 +39,7 @@ ;;; Request datatype: (defun geiser-con--make-request (con str cont &optional sender-buffer) - (list (cons :id (geiser-con--connection-inc-count con)) + (list (cons :id (and (car con) (geiser-con--connection-inc-count con))) (cons :string str) (cons :continuation cont) (cons :buffer (or sender-buffer (current-buffer))) @@ -81,13 +81,13 @@ (progn (geiser-log--error "Unexpected queue input:\n %s" in) (delete-region (point-min) (point-max))) (goto-char (point-max)) - (insert in) + (insert (geiser--strip-ansi in)) (goto-char (point-min)) (when (re-search-forward (tq-queue-head-regexp tq) nil t) (unwind-protect (funcall (tq-queue-head-fn tq) (tq-queue-head-closure tq) - (buffer-substring (point-min) (match-beginning 0))) + (buffer-substring (point-min) (point))) (delete-region (point-min) (point-max)) (tq-queue-pop tq))))))) @@ -110,6 +110,9 @@ (cons :count 0) (cons :completed (make-hash-table :weakness 'value)))) +(defsubst geiser-con--pending-requests-p (c) + (not (tq-queue-empty (geiser-con--connection-tq c)))) + (defsubst geiser-con--connection-process (c) (tq-process (cdr (assq :tq c)))) @@ -139,7 +142,7 @@ (defun geiser-con--connection-update-debugging (c txt) (let* ((dp (geiser-con--connection-debug-prompt c)) - (is-d (and (stringp dp) (string-match dp txt)))) + (is-d (and (stringp dp) (string-match-p dp txt)))) (geiser-con--connection-set-debugging c is-d) is-d)) @@ -157,7 +160,7 @@ new)) (defun geiser-con--has-entered-debugger (con answer) - (when-let ((p (car (last (split-string answer "\n" t))))) + (when-let* ((p (car (last (split-string answer "\n" t))))) (geiser-con--connection-update-debugging con p)) (geiser-con--connection-is-debugging con)) @@ -260,7 +263,8 @@ (defun geiser-con--send-string (con str cont &optional sbuf) (let ((req (geiser-con--make-request con str cont sbuf))) - (geiser-con--connection-add-request con req) + (when (geiser-con--request-id req) + (geiser-con--connection-add-request con req)) req)) (defvar geiser-connection-timeout 30000 @@ -268,24 +272,29 @@ (defun geiser-con--interrupt (con) "Interrupt any request being currently in process." - (when-let (proc (and con (geiser-con--connection-process con))) + (when-let* ((proc (and con (geiser-con--connection-process con)))) (when (process-live-p proc) (interrupt-process proc)))) (defun geiser-con--wait (req timeout) - "Wait up to TIMEOUT msecs for request REQ to finish, returning its result." + "Wait up to TIMEOUT msecs for request REQ to finish." (let* ((con (or (geiser-con--request-connection req) (error "Geiser connection not active"))) (proc (geiser-con--connection-process con)) (id (geiser-con--request-id req)) (timeout (/ (or timeout geiser-connection-timeout) 1000.0)) (step (/ timeout 10))) - (with-timeout (timeout (geiser-con--request-deactivate req)) - (condition-case nil - (while (and (geiser-con--connection-process con) - (not (geiser-con--connection-completed-p con id))) - (accept-process-output proc step)) - (error (geiser-con--request-deactivate req)))))) + (if (null (geiser-con--request-id req)) ;; request sent with paused conn + (when-let* ((cont (geiser-con--request-continuation req))) + (with-current-buffer (or (geiser-con--request-buffer req) + (current-buffer)) + (funcall cont '((result))))) + (with-timeout (timeout (geiser-con--request-deactivate req)) + (condition-case nil + (while (and (geiser-con--connection-process con) + (not (geiser-con--connection-completed-p con id))) + (accept-process-output proc step)) + (error (geiser-con--request-deactivate req))))))) (defun geiser-con--send-string/wait (con str cont &optional timeout sbuf) (when (and (stringp str) (not (string-blank-p str))) diff --git a/elisp/geiser-doc.el b/elisp/geiser-doc.el index 5d1d04b..36712b5 100644 --- a/elisp/geiser-doc.el +++ b/elisp/geiser-doc.el @@ -1,6 +1,6 @@ ;;; geiser-doc.el --- Accessing scheme-provided documentation -*- lexical-binding: t; -*- -;; Copyright (C) 2009-2016, 2021-2022, 2024 Jose Antonio Ortega Ruiz +;; Copyright (C) 2009-2016, 2021-2022, 2024, 2026 Jose Antonio Ortega Ruiz ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the Modified BSD License. You should @@ -185,9 +185,9 @@ value if the default action should be skipped.") (defun geiser-doc-goto-source (&rest _) "Go to the definition of this item." (interactive) - (when-let (link geiser-doc--buffer-link) + (when-let* ((link geiser-doc--buffer-link)) (with--geiser-implementation (geiser-doc--link-impl link) - (if-let (target (geiser-doc--link-target link)) + (if-let* ((target (geiser-doc--link-target link))) (geiser-edit-symbol target nil (point-marker)) (geiser-edit-module (geiser-doc--link-module link)))))) @@ -200,7 +200,7 @@ value if the default action should be skipped.") (defun geiser-doc-goto-manual (&rest _) "Go to the manual for this item." (interactive) - (when-let (link geiser-doc--buffer-link) + (when-let* ((link geiser-doc--buffer-link)) (let ((tm (geiser-doc--link-target link)) (mod (geiser-doc--link-module link)) (impl (geiser-doc--link-impl link))) diff --git a/elisp/geiser-edit.el b/elisp/geiser-edit.el index 0d47cbe..1251969 100644 --- a/elisp/geiser-edit.el +++ b/elisp/geiser-edit.el @@ -1,6 +1,6 @@ ;;; geiser-edit.el --- Scheme edit locations -*- lexical-binding: t; -*- -;; Copyright (C) 2009, 2010, 2012, 2013, 2019-2024 Jose Antonio Ortega Ruiz +;; Copyright (C) 2009, 2010, 2012, 2013, 2019-2026 Jose Antonio Ortega Ruiz ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the Modified BSD License. You should @@ -60,7 +60,7 @@ or following links in error buffers.") (cdr (assoc "name" loc))) (defsubst geiser-edit--location-file (loc) - (when-let ((file-name (cdr (assoc "file" loc)))) + (when-let* ((file-name (cdr (assoc "file" loc)))) (concat (or (file-remote-p default-directory) "") file-name))) @@ -93,10 +93,14 @@ or following links in error buffers.") "define*" "define-method" "define-class" - "define-struct"))) + "define-struct" + ;; SRFI 253 + "define-checked"))) (defconst geiser-edit--def-re* - (regexp-opt '("define-syntaxes" "define-values"))) + (regexp-opt '("define-syntaxes" "define-values" + ;; SRFI 273 + "define-values-checked"))) (defsubst geiser-edit--def-re (thing) (let ((sx (regexp-quote (format "%s" thing)))) @@ -136,7 +140,7 @@ or following links in error buffers.") (forward-line (max 0 (1- line)))) ((numberp pos) (goto-char pos))) (if (not col) - (when-let (pos (car (geiser-edit--find-def symbol))) + (when-let* ((pos (car (geiser-edit--find-def symbol)))) (goto-char pos)) (beginning-of-line) (forward-char col) @@ -155,11 +159,10 @@ or following links in error buffers.") (unless no-error (error "Couldn't find location for '%s'" symbol))))) -(defsubst geiser-edit--try-edit (symbol ret &optional method no-error) - (let ((res (geiser-eval--retort-result ret))) - (if (listp res) - (geiser-edit--try-edit-location symbol res method no-error) - (unless no-error (error "Couldn't find location for '%s'" symbol))))) +(defsubst geiser-edit--try-edit (symbol res &optional method no-error) + (if (listp res) + (geiser-edit--try-edit-location symbol res method no-error) + (unless no-error (error "Couldn't find location for '%s'" symbol)))) ;;; Links @@ -257,26 +260,30 @@ or following links in error buffers.") (defvar geiser-edit--symbol-history nil) +(defun geiser-edit-symbol-location (&optional symbol) + (let* ((symbol (or symbol + (geiser--symbol-at-point) + (error "No symbol at point"))) + (cmd `(:eval (:ge symbol-location ',symbol)))) + (geiser-eval--retort-result (geiser-eval--send/wait cmd)))) + (defun geiser-edit-symbol (symbol &optional method marker) "Asks for a symbol to edit, with completion." (interactive (list (geiser-completion--read-symbol "Edit symbol: " nil geiser-edit--symbol-history))) - (let ((cmd `(:eval (:ge symbol-location ',symbol)))) - (geiser-edit--try-edit symbol (geiser-eval--send/wait cmd) method) - (when marker (xref-push-marker-stack)))) + (geiser-edit--try-edit symbol (geiser-edit-symbol-location symbol) method) + (when marker (xref-push-marker-stack))) (defun geiser-edit-symbol-at-point (&optional arg) "Visit the definition of the symbol at point. With prefix, asks for the symbol to locate." (interactive "P") - (let* ((symbol (or (and (not arg) (geiser--symbol-at-point)) - (geiser-completion--read-symbol "Edit symbol: "))) - (cmd `(:eval (:ge symbol-location ',symbol))) - (marker (point-marker)) - (ret (ignore-errors (geiser-eval--send/wait cmd)))) - (if (geiser-edit--try-edit symbol ret nil t) + (let ((symbol (or (and (not arg) (geiser--symbol-at-point)) + (geiser-completion--read-symbol "Edit symbol: "))) + (marker (point-marker))) + (if (geiser-edit--try-edit symbol (geiser-edit-symbol-location symbol) nil t) (when marker (xref-push-marker-stack marker)) (unless (geiser-edit-module-at-point t) (error "Couldn't find location for '%s'" symbol))) @@ -290,11 +297,20 @@ With prefix, asks for the symbol to locate." (with-no-warnings (xref-pop-marker-stack)))) -(defun geiser-edit-module (module &optional method no-error) +(defun geiser-edit-module-location (&optional module) + (let* ((module (or module + (geiser-completion--module-at-point) + (error "No module at point"))) + (cmd `(:eval (:ge module-location '(:module ,module))))) + (geiser-eval--retort-result (geiser-eval--send/wait cmd)))) + +(defun geiser-edit-module (&optional module method no-error) "Asks for a module and opens it in a new buffer." (interactive (list (geiser-completion--read-module))) - (let ((cmd `(:eval (:ge module-location '(:module ,module))))) - (geiser-edit--try-edit module (geiser-eval--send/wait cmd) method no-error))) + (geiser-edit--try-edit module + (geiser-edit-module-location module) + method + no-error)) (defun geiser-edit-module-at-point (&optional no-error) "Opens a new window visiting the module at point." diff --git a/elisp/geiser-eval.el b/elisp/geiser-eval.el index 8f58c25..069dfb9 100644 --- a/elisp/geiser-eval.el +++ b/elisp/geiser-eval.el @@ -1,6 +1,6 @@ ;;; geiser-eval.el --- Sending scheme code for evaluation -*- lexical-binding: t; -*- -;; Copyright (C) 2009, 2010, 2011, 2012, 2013, 2015, 2021, 2023 Jose Antonio Ortega Ruiz +;; Copyright (C) 2009-2013, 2015, 2021, 2023, 2026 Jose Antonio Ortega Ruiz ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the Modified BSD License. You should @@ -150,7 +150,8 @@ module-exports, autodoc, callers, callees and generic-methods.") (geiser-con--send-string (geiser-eval--connection) (geiser-eval--code-str code) (lambda (s) - (setq geiser-eval--async-retort (geiser-eval--log s)) + (setq geiser-eval--async-retort + (geiser-eval--log s)) (funcall cont s)) buffer)) @@ -167,6 +168,9 @@ module-exports, autodoc, callers, callees and generic-methods.") buffer) sync-retort)) +(defun geiser-eval--pending-requests-p () + (geiser-con--pending-requests-p (geiser-eval--connection))) + (defun geiser-eval-interrupt () "Interrupt on-going evaluation, if any." (interactive) diff --git a/elisp/geiser-impl.el b/elisp/geiser-impl.el index f95034a..e4b33d6 100644 --- a/elisp/geiser-impl.el +++ b/elisp/geiser-impl.el @@ -1,6 +1,6 @@ ;;; geiser-impl.el --- Generic support for scheme implementations -*- lexical-binding: t; -*- -;; Copyright (C) 2009-2010, 2012-2013, 2015-2016, 2019, 2021-2022 Jose Antonio Ortega Ruiz +;; Copyright (C) 2009-2010, 2012-2013, 2015-2016, 2019, 2021-2022, 2025 Jose Antonio Ortega Ruiz ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the Modified BSD License. You should @@ -143,9 +143,9 @@ in order to determine its scheme flavour." (push (cons impl file) geiser-impl--load-files))) ;;;###autoload -(progn ;Copy the whole def to the autoloads file. -(defun geiser-activate-implementation (impl) - (add-to-list 'geiser-active-implementations impl))) +(progn ;Copy the whole def to the autoloads file. + (defun geiser-activate-implementation (impl) + (add-to-list 'geiser-active-implementations impl))) (defsubst geiser-deactivate-implementation (impl) (setq geiser-active-implementations diff --git a/elisp/geiser-mode.el b/elisp/geiser-mode.el index c8a9e0d..75162d4 100644 --- a/elisp/geiser-mode.el +++ b/elisp/geiser-mode.el @@ -1,6 +1,6 @@ ;;; geiser-mode.el --- Minor mode for scheme buffers -*- lexical-binding: t; -*- -;; Copyright (C) 2009-2017, 2020, 2022, 2024 Jose Antonio Ortega Ruiz +;; Copyright (C) 2009-2017, 2020, 2022, 2024, 2025 Jose Antonio Ortega Ruiz ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the Modified BSD License. You should @@ -244,16 +244,15 @@ With prefix, recursively macro-expand the resulting expression." all t)) -(defun geiser-set-scheme () +(defun geiser-set-scheme (impl) "Associates current buffer with a given Scheme implementation." - (interactive) + (interactive (list (geiser-impl--read-impl))) (save-excursion (geiser-syntax--remove-kws) - (let ((impl (geiser-impl--read-impl))) - (geiser-impl--set-buffer-implementation impl) - (geiser-repl--set-up-repl impl) - (geiser-syntax--add-kws) - (geiser-syntax--fontify)))) + (geiser-impl--set-buffer-implementation impl) + (geiser-repl--set-up-repl impl) + (geiser-syntax--add-kws) + (geiser-syntax--fontify))) (defun geiser-mode-switch-to-repl (arg) "Switches to Geiser REPL. diff --git a/elisp/geiser-repl.el b/elisp/geiser-repl.el index b8df566..76dac80 100644 --- a/elisp/geiser-repl.el +++ b/elisp/geiser-repl.el @@ -1,6 +1,6 @@ ;;; geiser-repl.el --- Geiser's REPL -*- lexical-binding: t; -*- -;; Copyright (C) 2009-2013, 2015-2016, 2018-2023 Jose Antonio Ortega Ruiz +;; Copyright (C) 2009-2013, 2015-2016, 2018-2023, 2026 Jose Antonio Ortega Ruiz ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the Modified BSD License. You should @@ -56,7 +56,7 @@ used to discover a buffer's project." (defun geiser-repl-project-root () "Use project.el, to determine a buffer's project root." - (when-let (p (project-current)) (project-root p))) + (when-let* ((p (project-current))) (project-root p))) (geiser-custom--defcustom geiser-repl-current-project-function #'geiser-repl-project-root @@ -235,12 +235,30 @@ See also `geiser-repl-startup-hook'." "The character that represents a closing super parentheses." :type 'character) +(geiser-custom--defcustom geiser-repl-classify-output-p nil + "Whether to classify REPL output by type (success/warning/error). + +When enabled, REPL output will be colored differently based on +whether it represents successful evaluation, a warning, or an error. +This classification is based on pattern matching of the output." + :type 'boolean) + + (geiser-custom--defface repl-input 'comint-highlight-input geiser-repl "evaluated input highlighting") (geiser-custom--defface repl-output 'font-lock-string-face geiser-repl "REPL output") +(geiser-custom--defface repl-output-success + 'font-lock-string-face geiser-repl "REPL output (success)") + +(geiser-custom--defface repl-output-warning + 'warning geiser-repl "REPL output (warnings)") + +(geiser-custom--defface repl-output-error + 'error geiser-repl "REPL output (errors)") + (geiser-custom--defface repl-prompt 'comint-highlight-prompt geiser-repl "REPL prompt") @@ -465,21 +483,55 @@ will be set up using `geiser-connect-local' when a REPL is started.") (setq header-line-format (format "Socket: %s" address))))) + +(defun geiser-repl--classify-output (start end) + "Classify output region as :success, :warning, or :error. +Returns the classification based on the first line of output. +Only used when `geiser-repl-classify-output-p' is non-nil." + (save-excursion + (goto-char start) + (let ((first-line (buffer-substring-no-properties + start + (min end (line-end-position))))) + (cond + ((string-match-p "raise-exception" first-line) :error) + ((string-match-p "warning:" first-line) :warning) + (t :success))))) + (defun geiser-repl--fontify-output-region (beg end) - "Apply highlighting to a REPL output region." + "Apply highlighting to a REPL output region. +If `geiser-repl-highlight-output-p' is enabled, applies syntax +highlighting. Otherwise, if `geiser-repl-classify-output-p' is +enabled, classifies output and applies appropriate face. If neither +is enabled, applies default output face." (remove-text-properties beg end '(font-lock-face nil face nil)) - (if geiser-repl-highlight-output-p - (geiser-syntax--fontify-syntax-region beg end) - (geiser-repl--fontify-plaintext beg end))) - -(defun geiser-repl--fontify-plaintext (start end) - "Fontify REPL output plainly." - (add-text-properties - start end - '(font-lock-fontified t - fontified t - font-lock-multiline t - font-lock-face geiser-font-lock-repl-output))) + (cond + (geiser-repl-highlight-output-p + (geiser-syntax--fontify-syntax-region beg end)) + (geiser-repl-classify-output-p + (let ((output-type (geiser-repl--classify-output beg end))) + (geiser-repl--fontify-plaintext beg end output-type))) + (t + (geiser-repl--fontify-plaintext beg end)))) + +(defun geiser-repl--fontify-plaintext (start end &optional output-type) + "Fontify REPL output plainly with appropriate face. +If OUTPUT-TYPE is provided and `geiser-repl-classify-output-p' is +enabled, it can be :success, :warning, or :error. Otherwise defaults +to standard output face." + (let ((face (if (and output-type geiser-repl-classify-output-p) + (pcase output-type + (:error 'geiser-font-lock-repl-output-error) + (:warning 'geiser-font-lock-repl-output-warning) + (:success 'geiser-font-lock-repl-output-success) + (_ 'geiser-font-lock-repl-output)) + 'geiser-font-lock-repl-output))) + (add-text-properties + start end + `(font-lock-fontified t + fontified t + font-lock-multiline t + font-lock-face ,face)))) (defun geiser-repl--narrow-to-prompt () "Narrow to active prompt region and return t, otherwise returns nil." @@ -533,13 +585,24 @@ will be set up using `geiser-connect-local' when a REPL is started.") (geiser--font-lock-ensure geiser-repl--last-output-start geiser-repl--last-output-end))) +(defsubst geiser-repl--prompt-rx () + (or (geiser-con--connection-prompt geiser-repl--connection) "\\b\\B")) + +(defsubst geiser-repl--debug-prompt-rx () + (or (geiser-con--connection-debug-prompt geiser-repl--connection) "\\b\\B")) + +(defun geiser-repl--matches-prompt-p (txt) + (and (stringp txt) + (or (string-match-p (geiser-repl--prompt-rx) txt) + (string-match-p (geiser-repl--debug-prompt-rx) txt)))) + (defun geiser-repl--output-filter (txt) (when (geiser-repl--find-output-region) (geiser-repl--treat-output-region)) (geiser-con--connection-update-debugging geiser-repl--connection txt) (geiser-image--replace-images geiser-repl-inline-images-p geiser-repl-auto-display-images-p) - (when (string-match-p (geiser-con--connection-prompt geiser-repl--connection) - txt) + (when (geiser-repl--matches-prompt-p txt) + (geiser-con--connection-activate geiser-repl--connection) (geiser-autodoc--disinhibit-autodoc))) (defun geiser-repl--check-version (impl) @@ -552,12 +615,12 @@ will be set up using `geiser-connect-local' when a REPL is started.") (defvar geiser-repl--last-scm-buffer) (defun geiser-repl--set-default-directory () - (when-let (root (funcall geiser-repl-current-project-function)) + (when-let* ((root (funcall geiser-repl-current-project-function))) (setq-local default-directory root))) (defun geiser-repl--set-up-load-path () (when geiser-repl-add-project-paths - (when-let (root (funcall geiser-repl-current-project-function)) + (when-let* ((root (funcall geiser-repl-current-project-function))) (dolist (p (cond ((eq t geiser-repl-add-project-paths) '(".")) ((listp geiser-repl-add-project-paths) geiser-repl-add-project-paths))) @@ -697,14 +760,16 @@ will be set up using `geiser-connect-local' when a REPL is started.") "Send CMD input string to the current REPL buffer. If SAVE-HISTORY is non-nil, save CMD in the REPL history." (when (and cmd (eq major-mode 'geiser-repl-mode)) - (geiser-repl--prepare-send) - (goto-char (point-max)) - (comint-kill-input) - (insert cmd) - (let ((comint-input-filter (if save-history - comint-input-filter - 'ignore))) - (comint-send-input nil t)))) + (if (geiser-eval--pending-requests-p) + (message "Waiting for scheme process...") + (geiser-repl--prepare-send) + (goto-char (point-max)) + (comint-kill-input) + (insert cmd) + (let ((comint-input-filter (if save-history + comint-input-filter + 'ignore))) + (comint-send-input nil t))))) (defun geiser-repl-interrupt () (interactive) @@ -751,8 +816,8 @@ If SAVE-HISTORY is non-nil, save CMD in the REPL history." (when (buffer-live-p geiser-repl--connection-buffer) (kill-buffer geiser-repl--connection-buffer) (setq geiser-repl--connection-buffer nil) - (when-let (a (geiser-repl--connection-address - geiser-impl--implementation)) + (when-let* ((a (geiser-repl--connection-address + geiser-impl--implementation))) (delete-file a)))) (dolist (buffer (buffer-list)) (when (buffer-live-p buffer) @@ -1100,7 +1165,7 @@ buffer." (geiser-repl-autoeval-mode 1)) (when geiser-repl-superparen-mode-p (geiser-repl-superparen-mode 1)) - + (add-hook 'comint-preoutput-filter-functions #'geiser--strip-ansi nil t) ;; enabling compilation-shell-minor-mode without the annoying highlighter (compilation-setup t)) @@ -1144,7 +1209,7 @@ over a Unix-domain socket." (or geiser-repl--arglist (geiser-repl--arglist impl))) (defun geiser-repl--call-in-repl (cmd) - (when-let (b (geiser-repl--repl/impl geiser-impl--implementation)) + (when-let* ((b (geiser-repl--repl/impl geiser-impl--implementation))) (save-window-excursion (with-current-buffer b (funcall cmd))))) diff --git a/elisp/geiser-syntax.el b/elisp/geiser-syntax.el index af750fb..1dc42cc 100644 --- a/elisp/geiser-syntax.el +++ b/elisp/geiser-syntax.el @@ -1,6 +1,6 @@ ;;; geiser-syntax.el --- Utilities for parsing scheme syntax -*- lexical-binding: t; -*- -;; Copyright (C) 2009-2016, 2019-2022 Jose Antonio Ortega Ruiz +;; Copyright (C) 2009-2016, 2019-2022, 2026 Jose Antonio Ortega Ruiz ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the Modified BSD License. You should @@ -194,7 +194,7 @@ implementation-specific entries for font-lock-keywords.") (defun geiser-syntax--read/ex-symbol () ;; #{foo bar}# style symbols (let ((tk (geiser-syntax--read/matching "{" "}"))) - (when-let (c (geiser-syntax--read/next-char)) + (when-let* ((c (geiser-syntax--read/next-char))) (when (char-equal ?\# c) (geiser-syntax--read/next-char) (cons 'atom (make-symbol (format "#{%s}#" tk))))))) @@ -438,7 +438,8 @@ implementation-specific entries for font-lock-keywords.") (not bns)))) (when name (push name locals)) (when (geiser-syntax--symbol-eq head 'case-lambda) - (dolist (n (and (> nesting 0) (caar (last form)))) + (dolist (n (and (> nesting 0) + (geiser-syntax--linearize (caar (last form))))) (when n (push n locals))) (setq rest (and (> nesting 0) (cdr form))) (setq use-names nil)) diff --git a/elisp/geiser.el b/elisp/geiser.el index a7aabb9..bb41a8c 100644 --- a/elisp/geiser.el +++ b/elisp/geiser.el @@ -1,6 +1,6 @@ ;;; geiser.el --- GNU Emacs and Scheme talk to each other -*- lexical-binding: t; -*- -;; Copyright (C) 2009-2013, 2015, 2018, 2021-2024 Jose Antonio Ortega Ruiz +;; Copyright (C) 2009-2013, 2015, 2018, 2021-2026 Jose Antonio Ortega Ruiz ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the Modified BSD License. You should @@ -13,7 +13,7 @@ ;; Homepage: https://gitlab.com/emacs-geiser/ ;; Package-Requires: ((emacs "27.1") (project "0.8.1")) ;; SPDX-License-Identifier: BSD-3-Clause -;; Version: 0.31.1 +;; Version: 0.33.2 ;;; Commentary: @@ -1,4 +1,26 @@ -* Version 0.32 + +* Version 0.33.2 (Aug 10, 2026) + + - Fix for chicken repl. + +* Version 0.33.1 (May 23, 2026) + + - Fix: no evaluations sent to REPLs that are waiting for input (e.g., + because a call to =read=). + +* Version 0.33 (May 3, 2026) + + - Project migrated to codeberg.org: https://codeberg.org/geiser + - New geiser-repl-classify-output-p flag that enables classification of REPL + outputs as error/warning/success with customizable faces + (geiser-repl-output-*). Thanks, Lorenzo. + - Fix completion for local variadic args (thanks, rvs314). + - Fix for company code locations (thanks, Daniel). + - Fix race condition between REPL and background evaluations (thanks, Ian). + - Fix for ansi escapes in connected REPLs (thanks, ewhispers and martian + hiauts). + +* Version 0.32 (August 10, 2024) - REPL: Fix for highlighting of 2-character input prompts (thanks to Macon Gambill) @@ -9,6 +31,8 @@ - Highlight only if show-paren-mode is enabled - Compatibility with electric-pair-mode + - REPL: Fix for debugger access affecting mainly Guile. + * Version 0.31.1 (September 1, 2024) - Code cleanups @@ -1,3 +1,9 @@ +#+html: <p align=right> +#+html: <a href="http://elpa.nongnu.org/nongnu/geiser.html"><img alt="NonGNU Elpa" src="http://elpa.nongnu.org/nongnu/geiser.svg"/> </a> +#+html: <a href="http://elpa.nongnu.org/nongnu-devel/geiser.html"><img alt="NonGNU Devel Elpa" src="http://elpa.nongnu.org/nongnu-devel/geiser.svg"/></a> +#+html: <a href="https://melpa.org/#/geiser"><img alt="MELPA" src="https://melpa.org/packages/geiser-badge.svg"/></a> +#+html: </p> + * Overview Geiser is a generic Emacs/Scheme interaction mode, featuring an @@ -33,15 +39,15 @@ The following schemes are supported via an independent package, installable from either NonGNU ELPA or MELPA: - - Chez 9.4 or better, via [[https://gitlab.com/emacs-geiser/chez][geiser-chez]] - - Chibi 0.7.3 or better, via [[https://gitlab.com/emacs-geiser/chibi][geiser-chibi]] - - Chicken 4.8.0 or better, via [[https://gitlab.com/emacs-geiser/chicken][geiser-chicken]] - - Gambit 4.9.3 or better, via [[https://gitlab.com/emacs-geiser/gambit][geiser-gambit]] + - Chez 9.4 or better, via [[https://codeberg.org/geiser/chez][geiser-chez]] + - Chibi 0.7.3 or better, via [[https://codeberg.org/geiser/chibi][geiser-chibi]] + - Chicken 4.8.0 or better, via [[https://codeberg.org/geiser/chicken][geiser-chicken]] + - Gambit 4.9.3 or better, via [[https://codeberg.org/geiser/gambit][geiser-gambit]] - Gauche 0.9.6 or better, via [[https://gitlab.com/emacs-geiser/gauche][geiser-gauche]] - - Guile 2.2 or better, via [[https://gitlab.com/emacs-geiser/guile][geiser-guile]] + - Guile 2.2 or better, via [[https://codeberg.org/geiser/guile][geiser-guile]] - Kawa 3.1, via [[https://gitlab.com/emacs-geiser/kawa][geiser-kawa]] - - MIT/GNU Scheme, via [[https://gitlab.com/emacs-geiser/mit][geiser-mit]] - - Racket 6.0 or better, via [[https://gitlab.com/emacs-geiser/racket][geiser-racket]] + - MIT/GNU Scheme, via [[https://codeberg.org/geiser/mit][geiser-mit]] + - Racket 6.0 or better, via [[https://codeberg.org/geiser/racket][geiser-racket]] - Stklos 1.50, via [[https://gitlab.com/emacs-geiser/stklos][geiser-stklos]] * Installation @@ -118,7 +124,7 @@ * Quick key reference - (See also [[http://geiser.nongnu.org/geiser_5.html#Cheat-sheet][the user's manual cheat sheet]]') + (See also [[https://geiser.nongnu.org/Cheat-sheet.html#Cheat-sheet][the user's manual cheat sheet]]') ** In Scheme buffers: @@ -214,7 +220,7 @@ To see what elisp functions one needs to implement, just execute the command `M-x geiser-implementation-help` inside emacs with a recent version of geiser installed. And then take a look at, say, - [[https://gitlab.com/emacs-geiser/guile/-/blob/master/geiser-guile.el][geiser-guile.el]] for examples of how those functions are implemented + [[https://codeberg.org/geiser/guile/src/branch/master/geiser-guile.el][geiser-guile.el]] for examples of how those functions are implemented for concrete schemes. Not all schemes can provide introspective information to implement all @@ -222,3 +228,12 @@ leave as many functions unimplemented as you see fit (there is even an explicit list of unsupported features), and geiser will still know how to use the ones that are implemented. + +* Contributing +*** Generative AI (LLMs) + + Use of generative AI (LLMs, diffusion models and similar technology) is not + acceptable for contributions to or interactions with the geiser project. + + This includes words, images and code, as well as bug reports, commit + messages, email (mailing list or private) and IRC messages. |
