From 52ef06f79e3f643520d76a9a3381f4c8dbe98a0d Mon Sep 17 00:00:00 2001 From: Timo Wilken Date: Tue, 14 Nov 2023 20:02:38 +0100 Subject: Load Lisp project automatically when entering REPL --- tw/home/files/emacs-init.el | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/tw/home/files/emacs-init.el b/tw/home/files/emacs-init.el index f26c790d..be09c4f6 100644 --- a/tw/home/files/emacs-init.el +++ b/tw/home/files/emacs-init.el @@ -503,7 +503,8 @@ If CREATE is true and the resulting directory does not exist, create it." (use-package sly :after (evil) - :hook (lisp-mode . sly-mode) ; `common-lisp-mode' is `lisp-mode'. + :hook ((lisp-mode . sly-mode) ; `common-lisp-mode' is `lisp-mode'. + (sly-mrepl-mode . tw/resize-repl-window)) :config (evil-define-key '(normal visual) lisp-mode-map (kbd "C-c") #'sly-interrupt @@ -871,7 +872,44 @@ For use in `org-latex-classes'." (use-package aggressive-indent :hook (scheme-mode emacs-lisp-mode common-lisp-mode sh-mode bash-ts-mode)) +(defun tw/find-asd-systems (directory) + "Return a list of Common Lisp .asd systems found in DIRECTORY." + (let ((asd-rx (rx ".asd" eos))) + (mapcar (lambda (file) + (string-trim-right file asd-rx)) + (directory-files directory nil asd-rx)))) + +(defun tw/lisp-project-setup () + "Set up a Lisp REPL for the current project." + (when-let ((fname (buffer-file-name)) + (project-directory + (or (locate-dominating-file fname "guix.scm") + (locate-dominating-file fname #'tw/find-asd-systems) + (project-current nil (file-name-directory fname))))) + (cd project-directory) + (setq-local + inferior-lisp-program + `(;; If a guix.scm file exists, run Lisp in a Guix shell to get dependencies. + ,@(and (file-exists-p (file-name-concat project-directory "guix.scm")) + '("guix" "shell" "-Df" "guix.scm" "--")) + "sbcl" "--noinform" + ;; Load all defined asdf systems using QuickLisp. + ,@(mapcan (lambda (system) + (list "--load" (format "%s.asd" system) + "--eval" (format "(ql:quickload '#:%s)" system))) + ;; Heuristic: shorter names are earlier in the dependency tree. + ;; For example, X-test.asd depends on X.asd. + (sort (tw/find-asd-systems project-directory) + (lambda (s1 s2) + (< (length s1) (length s2))))) + ;; Assume the project directory name is the name of the main package. + "--eval" ,(format "(in-package #:%s)" + (file-name-base + (directory-file-name project-directory))))))) + (use-package inf-lisp + :after (lisp-mode) + :hook (lisp-mode . tw/lisp-project-setup) :custom (inferior-lisp-program "sbcl")) -- cgit v1.2.3