用最新版本的 Emacs、SLIME和CCL來打造本身的 LispBox-0.8
首先得弄清楚 Lispbox 的啓動順序,以及各個部分(emacs、slime 、CCL 、quicklisp)如何被調用,大體描述以下:
一、執行 lispbox.bat ,實際上運行了以下命令 shell
runemacs.exe --no-init-file --no-site-file --eval=="(progn (load \"lispbox.el\") (slime))"
二、上面的命令至關於由 emacs 加載了 emacs-24.2\site-lisp\ 目錄下的 lispbox.el 文件,而後再執行 slime ,具體的lispbox.el 的內容以下:
windows
(require 'cl) (defun lispbox-list-to-filename (list) (apply #'concat (maplist #'(lambda (cons) (if (cdr cons) (file-name-as-directory (car cons)) (car cons))) list))) (defun lispbox-file (rest) (concat (file-name-as-directory (expand-file-name (or (getenv "LISPBOX_HOME") (file-name-directory load-file-name)))) rest)) (defun lispbox-find-lisps () (dolist (file (file-expand-wildcards (lispbox-file "*/lispbox-register.el"))) (load file))) (defun lispbox-install-lisp-license (license-path lisp-name) (let ((license (concat (file-name-directory load-file-name) (lispbox-list-to-filename license-path)))) (if (not (file-exists-p license)) (let* ((prompt (format "Need to install license for %s . Please enter name of file where you saved it: " lisp-name)) (to-install (read-file-name prompt))) (copy-file (expand-file-name to-install) license))))) (global-font-lock-mode t) (setq load-path (cons (lispbox-file "slime-2012-11-13") load-path)) ;(setenv "SBCL_HOME" (lispbox-file "sbcl-1.0.42/lib/sbcl")) (setenv "SBCL_HOME" (lispbox-file "Steel-Bank-Common-Lisp")) (setenv "CCL_DEFAULT_DIRECTORY" (lispbox-file "ccl-1.8-windowsx86")) ;(require :aserve) (require 'slime) (setq locale-coding-system 'utf-8) (set-terminal-coding-system 'utf-8) (set-keyboard-coding-system 'utf-8) (set-selection-coding-system 'utf-8) (set-default-coding-systems 'utf-8) (prefer-coding-system 'utf-8) (setq slime-net-coding-system 'utf-8-unix) (slime-setup '(slime-fancy slime-asdf slime-banner)) (lispbox-find-lisps) (provide 'lispbox)
;; 尋找 lispbox-register.el ,找到後加載 lispbox-register.el (defun lispbox-find-lisps () (dolist (file (file-expand-wildcards (lispbox-file "*/lispbox-register.el"))) (load file))) ;; 設置 slime 的路徑 (setq load-path (cons (lispbox-file "slime-2012-11-13") load-path)) ;; 設置 SBCL 的路徑 (setenv "SBCL_HOME" (lispbox-file "Steel-Bank-Common-Lisp")) ;; 設置 CCL 路徑 (setenv "CCL_DEFAULT_DIRECTORY" (lispbox-file "ccl-1.8-windowsx86")) (require 'slime) (setq slime-net-coding-system 'utf-8-unix) (slime-setup '(slime-fancy slime-asdf slime-banner)) ;; 在上述路徑中執行查找 lispbox-register.el 文件,找到後加載它 (lispbox-find-lisps) (provide 'lispbox)
三、從上述的 lispbox.el 中發現,下一個要加載的文件是 lispbox-register.el ,這個文件放在對應的 Lisp 編譯器目錄下,好比這裏我使用了兩種編譯器 SBCL 和 CCL,那麼就要在相應的目錄下準備好這個文件。
CCL 下的 lispbox-register.el 內容爲:
app
(push (list 'clozurecl (list (lispbox-list-to-filename (list (file-name-directory load-file-name) (if (getenv "PROGRAMW6432") "wx86cl64.exe" "wx86cl.exe"))))) slime-lisp-implementations)
(push (list 'sbcl (list (lispbox-list-to-filename (list (file-name-directory load-file-name) (if (getenv "PROGRAMW6432") "sbcl.exe" "sbcl.exe"))))) slime-lisp-implementations)
集成在 lispbox 中的 CCL-1.6 和單獨的 CCL-1.8 的區別: ide
一、lispbox 的 ccl-1.6-windowsx86 目錄下有一個 lispbox-register.el 的文件,單獨的 ccl-1.8-windowsx86 目錄下沒有此文件,該文件以下語句來設置: ui
(setq load-path (cons (lispbox-file "slime-2012-11-13") load-path)) (setenv "SBCL_HOME" (lispbox-file "sbcl-1.0.42/lib/sbcl")) (setenv "CCL_DEFAULT_DIRECTORY" (lispbox-file "ccl-1.8-windowsx86"))
二、ccl-1.6-windowsx86\tools\asdf.lisp 文件不一樣,直接把 ccl-1.8-windowsx86 文件夾拷貝過去後執行lispbox.bat EMACS啓動後會有以下提示:
;Compiler warnings for "f:/LISPBO~1.8/ccl-1.8-windowsx86/tools/asdf.lisp" :
; In ASDF::CCL-FASL-VERSION: Undefined function CCL::TARGET-FASL-VERSION unix
檢查後發現emacs顯示同時調用了1.6和1.8的CCL,把1.6的lispbox-register.el 改個名字就再也不顯示上面的錯誤了,可是又出現了不少新的警告提示,以下: rest
(progn (load "f:/LISPBO~1.8/slime-2012-11-13/swank-loader.lisp" :verbose t) (funcall (read-from-string "swank-loader:init")) (funcall (read-from-string "swank:start-server") "c:/Users/admin/AppData/Local/Temp/slime.5360")) Welcome to Clozure Common Lisp Version 1.8-r15286M (WindowsX8632)! ? ;Loading #P"f:/LISPBO~1.8/slime-2012-11-13/swank-loader.lisp"... ;Compiling "f:/LISPBO~1.8/slime-2012-11-13/swank-backend.lisp"... ;Compiler warnings for "f:/LISPBO~1.8/slime-2012-11-13/swank-backend.lisp" : ; In an anonymous lambda form at position 47772: Unused lexical variable THREAD ; In an anonymous lambda form at position 48339: Unused lexical variable NAME ;Loading #P"C:/Users/admin/.slime/fasl/2012-11-12/clozure-version_1.8-r15286m__(windowsx8632)-windows-x86/swank-backend.wx32fsl"... ;Compiling "f:/LISPBO~1.8/slime-2012-11-13/metering.lisp"... ;Loading #P"C:/Users/admin/.slime/fasl/2012-11-12/clozure-version_1.8-r15286m__(windowsx8632)-windows-x86/metering.wx32fsl"... ;Compiling "f:/LISPBO~1.8/slime-2012-11-13/swank-ccl.lisp"... ;Loading #P"C:/Users/admin/.slime/fasl/2012-11-12/clozure-version_1.8-r15286m__(windowsx8632)-windows-x86/swank-ccl.wx32fsl"... ;Compiling "f:/LISPBO~1.8/slime-2012-11-13/swank-gray.lisp"... ;Loading #P"C:/Users/admin/.slime/fasl/2012-11-12/clozure-version_1.8-r15286m__(windowsx8632)-windows-x86/swank-gray.wx32fsl"... ;Compiling "f:/LISPBO~1.8/slime-2012-11-13/swank-match.lisp"... ;Loading #P"C:/Users/admin/.slime/fasl/2012-11-12/clozure-version_1.8-r15286m__(windowsx8632)-windows-x86/swank-match.wx32fsl"... ;Compiling "f:/LISPBO~1.8/slime-2012-11-13/swank-rpc.lisp"... ;Loading #P"C:/Users/admin/.slime/fasl/2012-11-12/clozure-version_1.8-r15286m__(windowsx8632)-windows-x86/swank-rpc.wx32fsl"... ;Compiling "f:/LISPBO~1.8/slime-2012-11-13/swank.lisp"... ;Compiler warnings for "f:/LISPBO~1.8/slime-2012-11-13/swank.lisp" : ; In SWANK::THREAD-FOR-EVALUATION: Undefined function SWANK::FIND-REPL-THREAD ; In SWANK::THREAD-FOR-EVALUATION: Undefined function SWANK::FIND-REPL-THREAD ;Loading #P"C:/Users/admin/.slime/fasl/2012-11-12/clozure-version_1.8-r15286m__(windowsx8632)-windows-x86/swank.wx32fsl"... ; Warning: These Swank interfaces are unimplemented: ; (ACTIVATE-STEPPING ADD-FD-HANDLER ADD-SIGIO-HANDLER ; BACKGROUND-SAVE-IMAGE DUP EXEC-IMAGE MAKE-FD-STREAM ; REMOVE-FD-HANDLERS REMOVE-SIGIO-HANDLERS SLDB-BREAK-AT-START ; SLDB-BREAK-ON-RETURN SLDB-STEP-INTO SLDB-STEP-NEXT SLDB-STEP-OUT ; WAIT-FOR-INPUT) ; While executing: SWANK-BACKEND::WARN-UNIMPLEMENTED-INTERFACES, in process listener(1). ;Compiling "f:/LISPBO~1.8/slime-2012-11-13/contrib/swank-util.lisp"... ;Compiling "f:/LISPBO~1.8/slime-2012-11-13/contrib/swank-repl.lisp"... ;Compiling "f:/LISPBO~1.8/slime-2012-11-13/contrib/swank-c-p-c.lisp"... ;Compiling "f:/LISPBO~1.8/slime-2012-11-13/contrib/swank-arglists.lisp"... ;Compiling "f:/LISPBO~1.8/slime-2012-11-13/contrib/swank-fuzzy.lisp"... ;Compiling "f:/LISPBO~1.8/slime-2012-11-13/contrib/swank-fancy-inspector.lisp"... ;Compiling "f:/LISPBO~1.8/slime-2012-11-13/contrib/swank-presentations.lisp"... ;Compiler warnings for "f:/LISPBO~1.8/slime-2012-11-13/contrib/swank-presentations.lisp" : ; In an anonymous lambda form at position 8124: Undeclared free variable *SEND-REPL-RESULTS-FUNCTION* ;Compiling "f:/LISPBO~1.8/slime-2012-11-13/contrib/swank-presentation-streams.lisp"... ;Compiler warnings for "f:/LISPBO~1.8/slime-2012-11-13/contrib/swank-presentation-streams.lisp" : ; In an anonymous lambda form at position 12203: Undeclared free variable *SEND-REPL-RESULTS-FUNCTION* ;Compiler warnings for "f:/LISPBO~1.8/slime-2012-11-13/contrib/swank-presentation-streams.lisp" : ; In CCL::CLEAR-PRESENTATIONS inside an anonymous lambda form: Undefined function SWANK::CLEAR-PRESENTATION-TABLES ; In SWANK::PRESENTING-OBJECT-1: Undefined function SWANK::SAVE-PRESENTED-OBJECT ;Compiling "f:/LISPBO~1.8/slime-2012-11-13/contrib/swank-package-fu.lisp"... ;Compiling "f:/LISPBO~1.8/slime-2012-11-13/contrib/swank-hyperdoc.lisp"... ;Compiling "f:/LISPBO~1.8/slime-2012-11-13/contrib/swank-mrepl.lisp"... ;; Swank started at port: 50050. 50050 ? ; Warning: Test failed: (&KEY #'#'+) => "(&key (function (function +)))" ; Expected: "(&key (function #'+))" ; While executing: (:INTERNAL TEST TEST-PRINT-ARGLIST), in process worker(8).