PageRenderTime 61ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 2ms

/local-lisp/slime/slime.el

https://bitbucket.org/sakito/dot.emacs.d/
Emacs Lisp | 6535 lines | 5215 code | 853 blank | 467 comment | 221 complexity | a03978b2ffe6ea4e52b7e06603fc607d MD5 | raw file
Possible License(s): GPL-3.0, CC-BY-SA-4.0, GPL-2.0, Unlicense

Large files files are truncated, but you can click here to view the full file

  1. ;;; slime.el --- Superior Lisp Interaction Mode for Emacs
  2. ;;
  3. ;;;; License
  4. ;; Copyright (C) 2003 Eric Marsden, Luke Gorrie, Helmut Eller
  5. ;; Copyright (C) 2004,2005,2006 Luke Gorrie, Helmut Eller
  6. ;; Copyright (C) 2007,2008,2009 Helmut Eller, Tobias C. Rittweiler
  7. ;;
  8. ;; For a detailed list of contributors, see the manual.
  9. ;;
  10. ;; This program is free software; you can redistribute it and/or
  11. ;; modify it under the terms of the GNU General Public License as
  12. ;; published by the Free Software Foundation; either version 2 of
  13. ;; the License, or (at your option) any later version.
  14. ;;
  15. ;; This program is distributed in the hope that it will be useful,
  16. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. ;; GNU General Public License for more details.
  19. ;;
  20. ;; You should have received a copy of the GNU General Public
  21. ;; License along with this program; if not, write to the Free
  22. ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  23. ;; MA 02111-1307, USA.
  24. ;;;; Commentary
  25. ;;
  26. ;; This file contains extensions for programming in Common Lisp. The
  27. ;; main features are:
  28. ;;
  29. ;; A socket-based communication/RPC interface between Emacs and
  30. ;; Lisp, enabling introspection and remote development.
  31. ;;
  32. ;; The `slime-mode' minor-mode complementing `lisp-mode'. This new
  33. ;; mode includes many commands for interacting with the Common Lisp
  34. ;; process.
  35. ;;
  36. ;; A Common Lisp debugger written in Emacs Lisp. The debugger pops up
  37. ;; an Emacs buffer similar to the Emacs/Elisp debugger.
  38. ;;
  39. ;; A Common Lisp inspector to interactively look at run-time data.
  40. ;;
  41. ;; Trapping compiler messages and creating annotations in the source
  42. ;; file on the appropriate forms.
  43. ;;
  44. ;; SLIME should work with Emacs 22 and 23. If it works on XEmacs,
  45. ;; consider yourself lucky.
  46. ;;
  47. ;; In order to run SLIME, a supporting Lisp server called Swank is
  48. ;; required. Swank is distributed with slime.el and will automatically
  49. ;; be started in a normal installation.
  50. ;;;; Dependencies and setup
  51. (eval-and-compile
  52. (when (<= emacs-major-version 20)
  53. (error "Slime requires an Emacs version of 21, or above")))
  54. (eval-and-compile
  55. (require 'cl)
  56. (when (locate-library "hyperspec")
  57. (require 'hyperspec)))
  58. (require 'thingatpt)
  59. (require 'comint)
  60. (require 'timer)
  61. (require 'pp)
  62. (require 'hideshow)
  63. (require 'font-lock)
  64. (when (featurep 'xemacs)
  65. (require 'overlay))
  66. (require 'easymenu)
  67. (eval-when (compile)
  68. (require 'arc-mode)
  69. (require 'apropos)
  70. (require 'outline)
  71. (require 'etags)
  72. (require 'compile)
  73. (require 'gud))
  74. (eval-and-compile
  75. (defvar slime-path
  76. (let ((path (or (locate-library "slime") load-file-name)))
  77. (and path (file-name-directory path)))
  78. "Directory containing the Slime package.
  79. This is used to load the supporting Common Lisp library, Swank.
  80. The default value is automatically computed from the location of the
  81. Emacs Lisp package."))
  82. (defvar slime-lisp-modes '(lisp-mode))
  83. (defvar slime-setup-contribs nil)
  84. (defun slime-setup (&optional contribs)
  85. "Setup Emacs so that lisp-mode buffers always use SLIME.
  86. CONTRIBS is a list of contrib packages to load."
  87. (when (member 'lisp-mode slime-lisp-modes)
  88. (add-hook 'lisp-mode-hook 'slime-lisp-mode-hook))
  89. (setq slime-setup-contribs contribs)
  90. (slime-setup-contribs))
  91. (defun slime-setup-contribs ()
  92. "Load and initialize contribs."
  93. (when slime-setup-contribs
  94. (add-to-list 'load-path (expand-file-name "contrib" slime-path))
  95. (dolist (c slime-setup-contribs)
  96. (require c)
  97. (let ((init (intern (format "%s-init" c))))
  98. (when (fboundp init)
  99. (funcall init))))))
  100. (defun slime-lisp-mode-hook ()
  101. (slime-mode 1)
  102. (set (make-local-variable 'lisp-indent-function)
  103. 'common-lisp-indent-function))
  104. (eval-and-compile
  105. (defun slime-changelog-date (&optional interactivep)
  106. "Return the datestring of the latest entry in the ChangeLog file.
  107. Return nil if the ChangeLog file cannot be found."
  108. (interactive "p")
  109. (let ((changelog (concat slime-path "ChangeLog"))
  110. (date nil))
  111. (when (file-exists-p changelog)
  112. (with-temp-buffer
  113. (insert-file-contents-literally changelog nil 0 100)
  114. (goto-char (point-min))
  115. (setq date (symbol-name (read (current-buffer))))))
  116. (when interactivep
  117. (message "Slime ChangeLog dates %s." date))
  118. date)))
  119. (defvar slime-protocol-version nil)
  120. (setq slime-protocol-version
  121. (eval-when-compile (slime-changelog-date)))
  122. ;;;; Customize groups
  123. ;;
  124. ;;;;; slime
  125. (defgroup slime nil
  126. "Interaction with the Superior Lisp Environment."
  127. :prefix "slime-"
  128. :group 'applications)
  129. ;;;;; slime-ui
  130. (defgroup slime-ui nil
  131. "Interaction with the Superior Lisp Environment."
  132. :prefix "slime-"
  133. :group 'slime)
  134. (defcustom slime-truncate-lines t
  135. "Set `truncate-lines' in popup buffers.
  136. This applies to buffers that present lines as rows of data, such as
  137. debugger backtraces and apropos listings."
  138. :type 'boolean
  139. :group 'slime-ui)
  140. (defcustom slime-kill-without-query-p nil
  141. "If non-nil, kill SLIME processes without query when quitting Emacs.
  142. This applies to the *inferior-lisp* buffer and the network connections."
  143. :type 'boolean
  144. :group 'slime-ui)
  145. ;;;;; slime-lisp
  146. (defgroup slime-lisp nil
  147. "Lisp server configuration."
  148. :prefix "slime-"
  149. :group 'slime)
  150. (defcustom slime-backend "swank-loader.lisp"
  151. "The name of the Lisp file that loads the Swank server.
  152. This name is interpreted relative to the directory containing
  153. slime.el, but could also be set to an absolute filename."
  154. :type 'string
  155. :group 'slime-lisp)
  156. (defcustom slime-connected-hook nil
  157. "List of functions to call when SLIME connects to Lisp."
  158. :type 'hook
  159. :group 'slime-lisp)
  160. (defcustom slime-enable-evaluate-in-emacs nil
  161. "*If non-nil, the inferior Lisp can evaluate arbitrary forms in Emacs.
  162. The default is nil, as this feature can be a security risk."
  163. :type '(boolean)
  164. :group 'slime-lisp)
  165. (defcustom slime-lisp-host "127.0.0.1"
  166. "The default hostname (or IP address) to connect to."
  167. :type 'string
  168. :group 'slime-lisp)
  169. (defcustom slime-port 4005
  170. "Port to use as the default for `slime-connect'."
  171. :type 'integer
  172. :group 'slime-lisp)
  173. (defvar slime-net-valid-coding-systems
  174. '((iso-latin-1-unix nil "iso-latin-1-unix")
  175. (iso-8859-1-unix nil "iso-latin-1-unix")
  176. (binary nil "iso-latin-1-unix")
  177. (utf-8-unix t "utf-8-unix")
  178. (emacs-mule-unix t "emacs-mule-unix")
  179. (euc-jp-unix t "euc-jp-unix"))
  180. "A list of valid coding systems.
  181. Each element is of the form: (NAME MULTIBYTEP CL-NAME)")
  182. (defun slime-find-coding-system (name)
  183. "Return the coding system for the symbol NAME.
  184. The result is either an element in `slime-net-valid-coding-systems'
  185. of nil."
  186. (let ((probe (assq name slime-net-valid-coding-systems)))
  187. (when (and probe (if (fboundp 'check-coding-system)
  188. (ignore-errors (check-coding-system (car probe)))
  189. (eq (car probe) 'binary)))
  190. probe)))
  191. (defcustom slime-net-coding-system
  192. (car (find-if 'slime-find-coding-system
  193. slime-net-valid-coding-systems :key 'car))
  194. "Coding system used for network connections.
  195. See also `slime-net-valid-coding-systems'."
  196. :type (cons 'choice
  197. (mapcar (lambda (x)
  198. (list 'const (car x)))
  199. slime-net-valid-coding-systems))
  200. :group 'slime-lisp)
  201. ;;;;; slime-mode
  202. (defgroup slime-mode nil
  203. "Settings for slime-mode Lisp source buffers."
  204. :prefix "slime-"
  205. :group 'slime)
  206. (defcustom slime-find-definitions-function 'slime-find-definitions-rpc
  207. "Function to find definitions for a name.
  208. The function is called with the definition name, a string, as its
  209. argument."
  210. :type 'function
  211. :group 'slime-mode
  212. :options '(slime-find-definitions-rpc
  213. slime-etags-definitions
  214. (lambda (name)
  215. (append (slime-find-definitions-rpc name)
  216. (slime-etags-definitions name)))
  217. (lambda (name)
  218. (or (slime-find-definitions-rpc name)
  219. (and tags-table-list
  220. (slime-etags-definitions name))))))
  221. (defcustom slime-complete-symbol-function 'slime-simple-complete-symbol
  222. "*Function to perform symbol completion."
  223. :group 'slime-mode
  224. :type '(choice (const :tag "Simple" slime-simple-complete-symbol)
  225. (const :tag "Compound" slime-complete-symbol*)
  226. (const :tag "Fuzzy" slime-fuzzy-complete-symbol)))
  227. ;;;;; slime-mode-faces
  228. (defgroup slime-mode-faces nil
  229. "Faces in slime-mode source code buffers."
  230. :prefix "slime-"
  231. :group 'slime-mode)
  232. (defun slime-underline-color (color)
  233. "Return a legal value for the :underline face attribute based on COLOR."
  234. ;; In XEmacs the :underline attribute can only be a boolean.
  235. ;; In GNU it can be the name of a colour.
  236. (if (featurep 'xemacs)
  237. (if color t nil)
  238. color))
  239. (defface slime-error-face
  240. `((((class color) (background light))
  241. (:underline ,(slime-underline-color "red")))
  242. (((class color) (background dark))
  243. (:underline ,(slime-underline-color "red")))
  244. (t (:underline t)))
  245. "Face for errors from the compiler."
  246. :group 'slime-mode-faces)
  247. (defface slime-warning-face
  248. `((((class color) (background light))
  249. (:underline ,(slime-underline-color "orange")))
  250. (((class color) (background dark))
  251. (:underline ,(slime-underline-color "coral")))
  252. (t (:underline t)))
  253. "Face for warnings from the compiler."
  254. :group 'slime-mode-faces)
  255. (defface slime-style-warning-face
  256. `((((class color) (background light))
  257. (:underline ,(slime-underline-color "brown")))
  258. (((class color) (background dark))
  259. (:underline ,(slime-underline-color "gold")))
  260. (t (:underline t)))
  261. "Face for style-warnings from the compiler."
  262. :group 'slime-mode-faces)
  263. (defface slime-note-face
  264. `((((class color) (background light))
  265. (:underline ,(slime-underline-color "brown4")))
  266. (((class color) (background dark))
  267. (:underline ,(slime-underline-color "light goldenrod")))
  268. (t (:underline t)))
  269. "Face for notes from the compiler."
  270. :group 'slime-mode-faces)
  271. (defun slime-face-inheritance-possible-p ()
  272. "Return true if the :inherit face attribute is supported."
  273. (assq :inherit custom-face-attributes))
  274. (defface slime-highlight-face
  275. (if (slime-face-inheritance-possible-p)
  276. '((t (:inherit highlight :underline nil)))
  277. '((((class color) (background light))
  278. (:background "darkseagreen2"))
  279. (((class color) (background dark))
  280. (:background "darkolivegreen"))
  281. (t (:inverse-video t))))
  282. "Face for compiler notes while selected."
  283. :group 'slime-mode-faces)
  284. ;;;;; sldb
  285. (defgroup slime-debugger nil
  286. "Backtrace options and fontification."
  287. :prefix "sldb-"
  288. :group 'slime)
  289. (defmacro define-sldb-faces (&rest faces)
  290. "Define the set of SLDB faces.
  291. Each face specifiation is (NAME DESCRIPTION &optional PROPERTIES).
  292. NAME is a symbol; the face will be called sldb-NAME-face.
  293. DESCRIPTION is a one-liner for the customization buffer.
  294. PROPERTIES specifies any default face properties."
  295. `(progn ,@(loop for face in faces
  296. collect `(define-sldb-face ,@face))))
  297. (defmacro define-sldb-face (name description &optional default)
  298. (let ((facename (intern (format "sldb-%s-face" (symbol-name name)))))
  299. `(defface ,facename
  300. (list (list t ,default))
  301. ,(format "Face for %s." description)
  302. :group 'slime-debugger)))
  303. (define-sldb-faces
  304. (topline "the top line describing the error")
  305. (condition "the condition class")
  306. (section "the labels of major sections in the debugger buffer")
  307. (frame-label "backtrace frame numbers")
  308. (restart-type "restart names."
  309. (if (slime-face-inheritance-possible-p)
  310. '(:inherit font-lock-keyword-face)))
  311. (restart "restart descriptions")
  312. (restart-number "restart numbers (correspond to keystrokes to invoke)"
  313. '(:bold t))
  314. (frame-line "function names and arguments in the backtrace")
  315. (restartable-frame-line
  316. "frames which are surely restartable"
  317. '(:foreground "lime green"))
  318. (non-restartable-frame-line
  319. "frames which are surely not restartable")
  320. (detailed-frame-line
  321. "function names and arguments in a detailed (expanded) frame")
  322. (local-name "local variable names")
  323. (local-value "local variable values")
  324. (catch-tag "catch tags"))
  325. ;;;; Minor modes
  326. ;;;;; slime-mode
  327. (defvar slime-mode-indirect-map (make-sparse-keymap)
  328. "Empty keymap which has `slime-mode-map' as it's parent.
  329. This is a hack so that we can reinitilize the real slime-mode-map
  330. more easily. See `slime-init-keymaps'.")
  331. (define-minor-mode slime-mode
  332. "\\<slime-mode-map>\
  333. SLIME: The Superior Lisp Interaction Mode for Emacs (minor-mode).
  334. Commands to compile the current buffer's source file and visually
  335. highlight any resulting compiler notes and warnings:
  336. \\[slime-compile-and-load-file] - Compile and load the current buffer's file.
  337. \\[slime-compile-file] - Compile (but not load) the current buffer's file.
  338. \\[slime-compile-defun] - Compile the top-level form at point.
  339. Commands for visiting compiler notes:
  340. \\[slime-next-note] - Goto the next form with a compiler note.
  341. \\[slime-previous-note] - Goto the previous form with a compiler note.
  342. \\[slime-remove-notes] - Remove compiler-note annotations in buffer.
  343. Finding definitions:
  344. \\[slime-edit-definition] - Edit the definition of the function called at point.
  345. \\[slime-pop-find-definition-stack] - Pop the definition stack to go back from a definition.
  346. Documentation commands:
  347. \\[slime-describe-symbol] - Describe symbol.
  348. \\[slime-apropos] - Apropos search.
  349. \\[slime-disassemble-symbol] - Disassemble a function.
  350. Evaluation commands:
  351. \\[slime-eval-defun] - Evaluate top-level from containing point.
  352. \\[slime-eval-last-expression] - Evaluate sexp before point.
  353. \\[slime-pprint-eval-last-expression] - Evaluate sexp before point, pretty-print result.
  354. Full set of commands:
  355. \\{slime-mode-map}"
  356. nil
  357. nil
  358. slime-mode-indirect-map
  359. (slime-setup-command-hooks)
  360. (setq slime-modeline-string (slime-modeline-string)))
  361. ;;;;;; Modeline
  362. ;; For XEmacs only
  363. (make-variable-buffer-local
  364. (defvar slime-modeline-string nil
  365. "The string that should be displayed in the modeline."))
  366. (add-to-list 'minor-mode-alist
  367. `(slime-mode ,(if (featurep 'xemacs)
  368. 'slime-modeline-string
  369. '(:eval (slime-modeline-string)))))
  370. (defun slime-modeline-string ()
  371. "Return the string to display in the modeline.
  372. \"Slime\" only appears if we aren't connected. If connected,
  373. include package-name, connection-name, and possibly some state
  374. information."
  375. (let ((conn (slime-current-connection)))
  376. ;; Bail out early in case there's no connection, so we won't
  377. ;; implicitly invoke `slime-connection' which may query the user.
  378. (if (not conn)
  379. (and slime-mode " Slime")
  380. (let ((local (eq conn slime-buffer-connection))
  381. (pkg (slime-current-package)))
  382. (concat " "
  383. (if local "{" "[")
  384. (if pkg (slime-pretty-package-name pkg) "?")
  385. " "
  386. ;; ignore errors for closed connections
  387. (ignore-errors (slime-connection-name conn))
  388. (slime-modeline-state-string conn)
  389. (if local "}" "]"))))))
  390. (defun slime-pretty-package-name (name)
  391. "Return a pretty version of a package name NAME."
  392. (cond ((string-match "^#?:\\(.*\\)$" name)
  393. (match-string 1 name))
  394. ((string-match "^\"\\(.*\\)\"$" name)
  395. (match-string 1 name))
  396. (t name)))
  397. (defun slime-modeline-state-string (conn)
  398. "Return a string possibly describing CONN's state."
  399. (cond ((not (eq (process-status conn) 'open))
  400. (format " %s" (process-status conn)))
  401. ((let ((pending (length (slime-rex-continuations conn)))
  402. (sldbs (length (sldb-buffers conn))))
  403. (cond ((and (zerop sldbs) (zerop pending)) nil)
  404. ((zerop sldbs) (format " %s" pending))
  405. (t (format " %s/%s" pending sldbs)))))))
  406. (defmacro slime-recompute-modelines ()
  407. ;; Avoid a needless runtime funcall on GNU Emacs:
  408. (and (featurep 'xemacs) `(slime-xemacs-recompute-modelines)))
  409. (defun slime-xemacs-recompute-modelines ()
  410. (let (redraw-modeline)
  411. (walk-windows
  412. (lambda (object)
  413. (setq object (window-buffer object))
  414. (when (or (symbol-value-in-buffer 'slime-mode object)
  415. (symbol-value-in-buffer 'slime-popup-buffer-mode object))
  416. ;; Only do the unwind-protect of #'with-current-buffer if we're
  417. ;; actually interested in this buffer
  418. (with-current-buffer object
  419. (setq redraw-modeline
  420. (or (not (equal slime-modeline-string
  421. (setq slime-modeline-string
  422. (slime-modeline-string))))
  423. redraw-modeline)))))
  424. 'never 'visible)
  425. (and redraw-modeline (redraw-modeline t))))
  426. (and (featurep 'xemacs)
  427. (pushnew 'slime-xemacs-recompute-modelines pre-idle-hook))
  428. ;;;;; Key bindings
  429. (defvar slime-parent-map nil
  430. "Parent keymap for shared between all Slime related modes.")
  431. (defvar slime-parent-bindings
  432. '(("\M-." slime-edit-definition)
  433. ("\M-," slime-pop-find-definition-stack)
  434. ("\M-_" slime-edit-uses) ; for German layout
  435. ("\M-?" slime-edit-uses) ; for USian layout
  436. ("\C-x4." slime-edit-definition-other-window)
  437. ("\C-x5." slime-edit-definition-other-frame)
  438. ("\C-x\C-e" slime-eval-last-expression)
  439. ("\C-\M-x" slime-eval-defun)
  440. ;; Include PREFIX keys...
  441. ("\C-c" slime-prefix-map)))
  442. (defvar slime-prefix-map nil
  443. "Keymap for commands prefixed with `slime-prefix-key'.")
  444. (defvar slime-prefix-bindings
  445. '(("\C-r" slime-eval-region)
  446. (":" slime-interactive-eval)
  447. ("\C-e" slime-interactive-eval)
  448. ("E" slime-edit-value)
  449. ("\C-l" slime-load-file)
  450. ("\C-b" slime-interrupt)
  451. ("\M-d" slime-disassemble-symbol)
  452. ("\C-t" slime-toggle-trace-fdefinition)
  453. ("I" slime-inspect)
  454. ("\C-xt" slime-list-threads)
  455. ("\C-xn" slime-cycle-connections)
  456. ("\C-xc" slime-list-connections)
  457. ("<" slime-list-callers)
  458. (">" slime-list-callees)
  459. ;; Include DOC keys...
  460. ("\C-d" slime-doc-map)
  461. ;; Include XREF WHO-FOO keys...
  462. ("\C-w" slime-who-map)
  463. ))
  464. (defvar slime-editing-map nil
  465. "These keys are useful for buffers where the user can insert and
  466. edit s-exprs, e.g. for source buffers and the REPL.")
  467. (defvar slime-editing-keys
  468. `(;; Arglist display & completion
  469. ("\M-\t" slime-complete-symbol)
  470. (" " slime-space)
  471. ;; Evaluating
  472. ;;("\C-x\M-e" slime-eval-last-expression-display-output :inferior t)
  473. ("\C-c\C-p" slime-pprint-eval-last-expression)
  474. ;; Macroexpand
  475. ("\C-c\C-m" slime-macro/compiler-macro-expand-1)
  476. ("\C-c\M-m" slime-macroexpand-all)
  477. ;; Misc
  478. ("\C-c\C-u" slime-undefine-function)
  479. (,(kbd "C-M-.") slime-next-location)
  480. (,(kbd "C-M-,") slime-previous-location)
  481. ;; Obsolete, redundant bindings
  482. ("\C-c\C-i" slime-complete-symbol)
  483. ;;("\M-*" pop-tag-mark) ; almost to clever
  484. ))
  485. (defvar slime-mode-map nil
  486. "Keymap for slime-mode.")
  487. (defvar slime-keys
  488. '( ;; Compiler notes
  489. ("\M-p" slime-previous-note)
  490. ("\M-n" slime-next-note)
  491. ("\C-c\M-c" slime-remove-notes)
  492. ("\C-c\C-k" slime-compile-and-load-file)
  493. ("\C-c\M-k" slime-compile-file)
  494. ("\C-c\C-c" slime-compile-defun)))
  495. (defun slime-nop ()
  496. "The null command. Used to shadow currently-unused keybindings."
  497. (interactive)
  498. (call-interactively 'undefined))
  499. (defvar slime-doc-map nil
  500. "Keymap for documentation commands. Bound to a prefix key.")
  501. (defvar slime-doc-bindings
  502. '((?a slime-apropos)
  503. (?z slime-apropos-all)
  504. (?p slime-apropos-package)
  505. (?d slime-describe-symbol)
  506. (?f slime-describe-function)
  507. (?h slime-documentation-lookup)
  508. (?~ common-lisp-hyperspec-format)
  509. (?# common-lisp-hyperspec-lookup-reader-macro)))
  510. (defvar slime-who-map nil
  511. "Keymap for who-xref commands. Bound to a prefix key.")
  512. (defvar slime-who-bindings
  513. '((?c slime-who-calls)
  514. (?w slime-calls-who)
  515. (?r slime-who-references)
  516. (?b slime-who-binds)
  517. (?s slime-who-sets)
  518. (?m slime-who-macroexpands)
  519. (?a slime-who-specializes)))
  520. (defun slime-init-keymaps ()
  521. "(Re)initialize the keymaps for `slime-mode'."
  522. (interactive)
  523. (slime-init-keymap 'slime-doc-map t t slime-doc-bindings)
  524. (slime-init-keymap 'slime-who-map t t slime-who-bindings)
  525. (slime-init-keymap 'slime-prefix-map t nil slime-prefix-bindings)
  526. (slime-init-keymap 'slime-parent-map nil nil slime-parent-bindings)
  527. (slime-init-keymap 'slime-editing-map nil nil slime-editing-keys)
  528. (set-keymap-parent slime-editing-map slime-parent-map)
  529. (slime-init-keymap 'slime-mode-map nil nil slime-keys)
  530. (set-keymap-parent slime-mode-map slime-editing-map)
  531. (set-keymap-parent slime-mode-indirect-map slime-mode-map))
  532. (defun slime-init-keymap (keymap-name prefixp bothp bindings)
  533. (set keymap-name (make-sparse-keymap))
  534. (when prefixp (define-prefix-command keymap-name))
  535. (slime-bind-keys (eval keymap-name) bothp bindings))
  536. (defun slime-bind-keys (keymap bothp bindings)
  537. "Add BINDINGS to KEYMAP.
  538. If BOTHP is true also add bindings with control modifier."
  539. (loop for (key command) in bindings do
  540. (cond (bothp
  541. (define-key keymap `[,key] command)
  542. (unless (equal key ?h) ; But don't bind C-h
  543. (define-key keymap `[(control ,key)] command)))
  544. (t (define-key keymap key command)))))
  545. (slime-init-keymaps)
  546. (define-minor-mode slime-editing-mode
  547. "Minor mode which makes slime-editing-map available.
  548. \\{slime-editing-map}"
  549. nil
  550. nil
  551. slime-editing-map)
  552. ;;;; Setup initial `slime-mode' hooks
  553. (make-variable-buffer-local
  554. (defvar slime-pre-command-actions nil
  555. "List of functions to execute before the next Emacs command.
  556. This list of flushed between commands."))
  557. (defun slime-pre-command-hook ()
  558. "Execute all functions in `slime-pre-command-actions', then NIL it."
  559. (dolist (undo-fn slime-pre-command-actions)
  560. (funcall undo-fn))
  561. (setq slime-pre-command-actions nil))
  562. (defun slime-post-command-hook ()
  563. (when (null pre-command-hook) ; sometimes this is lost
  564. (add-hook 'pre-command-hook 'slime-pre-command-hook)))
  565. (defun slime-setup-command-hooks ()
  566. "Setup a buffer-local `pre-command-hook' to call `slime-pre-command-hook'."
  567. (slime-add-local-hook 'pre-command-hook 'slime-pre-command-hook)
  568. (slime-add-local-hook 'post-command-hook 'slime-post-command-hook))
  569. ;;;; Framework'ey bits
  570. ;;;
  571. ;;; This section contains some standard SLIME idioms: basic macros,
  572. ;;; ways of showing messages to the user, etc. All the code in this
  573. ;;; file should use these functions when applicable.
  574. ;;;
  575. ;;;;; Syntactic sugar
  576. (defmacro* when-let ((var value) &rest body)
  577. "Evaluate VALUE, if the result is non-nil bind it to VAR and eval BODY.
  578. \(fn (VAR VALUE) &rest BODY)"
  579. `(let ((,var ,value))
  580. (when ,var ,@body)))
  581. (put 'when-let 'lisp-indent-function 1)
  582. (defmacro destructure-case (value &rest patterns)
  583. "Dispatch VALUE to one of PATTERNS.
  584. A cross between `case' and `destructuring-bind'.
  585. The pattern syntax is:
  586. ((HEAD . ARGS) . BODY)
  587. The list of patterns is searched for a HEAD `eq' to the car of
  588. VALUE. If one is found, the BODY is executed with ARGS bound to the
  589. corresponding values in the CDR of VALUE."
  590. (let ((operator (gensym "op-"))
  591. (operands (gensym "rand-"))
  592. (tmp (gensym "tmp-")))
  593. `(let* ((,tmp ,value)
  594. (,operator (car ,tmp))
  595. (,operands (cdr ,tmp)))
  596. (case ,operator
  597. ,@(mapcar (lambda (clause)
  598. (if (eq (car clause) t)
  599. `(t ,@(cdr clause))
  600. (destructuring-bind ((op &rest rands) &rest body) clause
  601. `(,op (destructuring-bind ,rands ,operands
  602. . ,body)))))
  603. patterns)
  604. ,@(if (eq (caar (last patterns)) t)
  605. '()
  606. `((t (error "Elisp destructure-case failed: %S" ,tmp))))))))
  607. (put 'destructure-case 'lisp-indent-function 1)
  608. (defmacro slime-define-keys (keymap &rest key-command)
  609. "Define keys in KEYMAP. Each KEY-COMMAND is a list of (KEY COMMAND)."
  610. `(progn . ,(mapcar (lambda (k-c) `(define-key ,keymap . ,k-c))
  611. key-command)))
  612. (put 'slime-define-keys 'lisp-indent-function 1)
  613. (defmacro* with-struct ((conc-name &rest slots) struct &body body)
  614. "Like with-slots but works only for structs.
  615. \(fn (CONC-NAME &rest SLOTS) STRUCT &body BODY)"
  616. (flet ((reader (slot) (intern (concat (symbol-name conc-name)
  617. (symbol-name slot)))))
  618. (let ((struct-var (gensym "struct")))
  619. `(let ((,struct-var ,struct))
  620. (symbol-macrolet
  621. ,(mapcar (lambda (slot)
  622. (etypecase slot
  623. (symbol `(,slot (,(reader slot) ,struct-var)))
  624. (cons `(,(first slot) (,(reader (second slot))
  625. ,struct-var)))))
  626. slots)
  627. . ,body)))))
  628. (put 'with-struct 'lisp-indent-function 2)
  629. ;;;;; Very-commonly-used functions
  630. (defvar slime-message-function 'message)
  631. ;; Interface
  632. (defun slime-buffer-name (type &optional hidden)
  633. (assert (keywordp type))
  634. (concat (if hidden " " "")
  635. (format "*slime-%s*" (substring (symbol-name type) 1))))
  636. ;; Interface
  637. (defun slime-message (format &rest args)
  638. "Like `message' but with special support for multi-line messages.
  639. Single-line messages use the echo area."
  640. (apply slime-message-function format args))
  641. (defun slime-display-warning (message &rest args)
  642. (display-warning '(slime warning) (apply #'format message args)))
  643. (defvar slime-background-message-function 'slime-display-oneliner)
  644. ;; Interface
  645. (defun slime-background-message (format-string &rest format-args)
  646. "Display a message in passing.
  647. This is like `slime-message', but less distracting because it
  648. will never pop up a buffer or display multi-line messages.
  649. It should be used for \"background\" messages such as argument lists."
  650. (apply slime-background-message-function format-string format-args))
  651. (defun slime-display-oneliner (format-string &rest format-args)
  652. (let* ((msg (apply #'format format-string format-args)))
  653. (unless (minibuffer-window-active-p (minibuffer-window))
  654. (message "%s" (slime-oneliner msg)))))
  655. (defun slime-oneliner (string)
  656. "Return STRING truncated to fit in a single echo-area line."
  657. (substring string 0 (min (length string)
  658. (or (position ?\n string) most-positive-fixnum)
  659. (1- (frame-width)))))
  660. ;; Interface
  661. (defun slime-set-truncate-lines ()
  662. "Apply `slime-truncate-lines' to the current buffer."
  663. (when slime-truncate-lines
  664. (set (make-local-variable 'truncate-lines) t)))
  665. ;; Interface
  666. (defun slime-read-package-name (prompt &optional initial-value)
  667. "Read a package name from the minibuffer, prompting with PROMPT."
  668. (let ((completion-ignore-case t))
  669. (completing-read prompt (slime-bogus-completion-alist
  670. (slime-eval
  671. `(swank:list-all-package-names t)))
  672. nil t initial-value)))
  673. ;; Interface
  674. (defun slime-read-symbol-name (prompt &optional query)
  675. "Either read a symbol name or choose the one at point.
  676. The user is prompted if a prefix argument is in effect, if there is no
  677. symbol at point, or if QUERY is non-nil."
  678. (cond ((or current-prefix-arg query (not (slime-symbol-at-point)))
  679. (slime-read-from-minibuffer prompt (slime-symbol-at-point)))
  680. (t (slime-symbol-at-point))))
  681. ;; Interface
  682. (defmacro slime-propertize-region (props &rest body)
  683. "Execute BODY and add PROPS to all the text it inserts.
  684. More precisely, PROPS are added to the region between the point's
  685. positions before and after executing BODY."
  686. (let ((start (gensym)))
  687. `(let ((,start (point)))
  688. (prog1 (progn ,@body)
  689. (add-text-properties ,start (point) ,props)))))
  690. (put 'slime-propertize-region 'lisp-indent-function 1)
  691. (defun slime-add-face (face string)
  692. (add-text-properties 0 (length string) (list 'face face) string)
  693. string)
  694. (put 'slime-add-face 'lisp-indent-function 1)
  695. ;; Interface
  696. (defsubst slime-insert-propertized (props &rest args)
  697. "Insert all ARGS and then add text-PROPS to the inserted text."
  698. (slime-propertize-region props (apply #'insert args)))
  699. (defmacro slime-with-rigid-indentation (level &rest body)
  700. "Execute BODY and then rigidly indent its text insertions.
  701. Assumes all insertions are made at point."
  702. (let ((start (gensym)) (l (gensym)))
  703. `(let ((,start (point)) (,l ,(or level '(current-column))))
  704. (prog1 (progn ,@body)
  705. (slime-indent-rigidly ,start (point) ,l)))))
  706. (put 'slime-with-rigid-indentation 'lisp-indent-function 1)
  707. (defun slime-indent-rigidly (start end column)
  708. ;; Similar to `indent-rigidly' but doesn't inherit text props.
  709. (let ((indent (make-string column ?\ )))
  710. (save-excursion
  711. (goto-char end)
  712. (beginning-of-line)
  713. (while (and (<= start (point))
  714. (progn
  715. (insert-before-markers indent)
  716. (zerop (forward-line -1))))))))
  717. (defun slime-insert-indented (&rest strings)
  718. "Insert all arguments rigidly indented."
  719. (slime-with-rigid-indentation nil
  720. (apply #'insert strings)))
  721. (defun slime-property-bounds (prop)
  722. "Return two the positions of the previous and next changes to PROP.
  723. PROP is the name of a text property."
  724. (assert (get-text-property (point) prop))
  725. (let ((end (next-single-char-property-change (point) prop)))
  726. (list (previous-single-char-property-change end prop) end)))
  727. (defun slime-curry (fun &rest args)
  728. "Partially apply FUN to ARGS. The result is a new function.
  729. This idiom is preferred over `lexical-let'."
  730. `(lambda (&rest more) (apply ',fun (append ',args more))))
  731. (defun slime-rcurry (fun &rest args)
  732. "Like `slime-curry' but ARGS on the right are applied."
  733. `(lambda (&rest more) (apply ',fun (append more ',args))))
  734. ;;;;; Temporary popup buffers
  735. (defvar slime-popup-restore-data nil
  736. "Data needed when closing popup windows.
  737. This is used as buffer local variable.
  738. The format is (POPUP-WINDOW SELECTED-WINDOW OLD-BUFFER).
  739. POPUP-WINDOW is the window used to display the temp buffer.
  740. That window may have been reused or freshly created.
  741. SELECTED-WINDOW is the window that was selected before displaying
  742. the popup buffer.
  743. OLD-BUFFER is the buffer that was previously displayed in POPUP-WINDOW.
  744. OLD-BUFFER is nil if POPUP-WINDOW was newly created.
  745. See `view-return-to-alist' for a similar idea.")
  746. ;; keep compiler quiet
  747. (defvar slime-buffer-package)
  748. (defvar slime-buffer-connection)
  749. ;; Interface
  750. (defmacro* slime-with-popup-buffer ((name &key package connection select mode)
  751. &body body)
  752. "Similar to `with-output-to-temp-buffer'.
  753. Bind standard-output and initialize some buffer-local variables.
  754. Restore window configuration when closed.
  755. NAME is the name of the buffer to be created.
  756. PACKAGE is the value `slime-buffer-package'.
  757. CONNECTION is the value for `slime-buffer-connection'.
  758. MODE is the name of a major mode which will be enabled.
  759. If nil, no explicit connection is associated with
  760. the buffer. If t, the current connection is taken.
  761. "
  762. `(let* ((vars% (list ,(if (eq package t) '(slime-current-package) package)
  763. ,(if (eq connection t) '(slime-connection) connection)))
  764. (standard-output (slime-make-popup-buffer ,name vars% ,mode)))
  765. (with-current-buffer standard-output
  766. (prog1 (progn ,@body)
  767. (assert (eq (current-buffer) standard-output))
  768. (setq buffer-read-only t)
  769. (set-window-point (slime-display-popup-buffer ,(or select nil))
  770. (point))))))
  771. (put 'slime-with-popup-buffer 'lisp-indent-function 1)
  772. (defun slime-make-popup-buffer (name buffer-vars mode)
  773. "Return a temporary buffer called NAME.
  774. The buffer also uses the minor-mode `slime-popup-buffer-mode'."
  775. (with-current-buffer (get-buffer-create name)
  776. (kill-all-local-variables)
  777. (when mode
  778. (funcall mode))
  779. (setq buffer-read-only nil)
  780. (erase-buffer)
  781. (set-syntax-table lisp-mode-syntax-table)
  782. (slime-init-popup-buffer buffer-vars)
  783. (current-buffer)))
  784. (defun slime-init-popup-buffer (buffer-vars)
  785. (slime-popup-buffer-mode 1)
  786. (multiple-value-setq (slime-buffer-package slime-buffer-connection)
  787. buffer-vars))
  788. (defun slime-display-popup-buffer (select)
  789. "Display the current buffer.
  790. Save the selected-window in a buffer-local variable, so that we
  791. can restore it later."
  792. (let ((selected-window (selected-window))
  793. (old-windows))
  794. (walk-windows (lambda (w) (push (cons w (window-buffer w)) old-windows))
  795. nil t)
  796. (let ((new-window (display-buffer (current-buffer))))
  797. (unless slime-popup-restore-data
  798. (set (make-local-variable 'slime-popup-restore-data)
  799. (list new-window
  800. selected-window
  801. (cdr (find new-window old-windows :key #'car)))))
  802. (when select
  803. (select-window new-window))
  804. new-window)))
  805. (defun slime-close-popup-window ()
  806. (when slime-popup-restore-data
  807. (destructuring-bind (popup-window selected-window old-buffer)
  808. slime-popup-restore-data
  809. (kill-local-variable 'slime-popup-restore-data)
  810. (bury-buffer)
  811. (when (eq popup-window (selected-window))
  812. (cond ((and (not old-buffer) (not (one-window-p)))
  813. (delete-window popup-window))
  814. ((and old-buffer (buffer-live-p old-buffer))
  815. (set-window-buffer popup-window old-buffer))))
  816. (when (window-live-p selected-window)
  817. (select-window selected-window)))))
  818. (defmacro slime-save-local-variables (vars &rest body)
  819. (let ((vals (make-symbol "vals")))
  820. `(let ((,vals (mapcar (lambda (var)
  821. (if (slime-local-variable-p var)
  822. (cons var (eval var))))
  823. ',vars)))
  824. (prog1 (progn . ,body)
  825. (mapc (lambda (var+val)
  826. (when (consp var+val)
  827. (set (make-local-variable (car var+val)) (cdr var+val))))
  828. ,vals)))))
  829. (put 'slime-save-local-variables 'lisp-indent-function 1)
  830. (define-minor-mode slime-popup-buffer-mode
  831. "Mode for displaying read only stuff"
  832. nil
  833. nil
  834. '(("q" . slime-popup-buffer-quit-function)
  835. ;;("\C-c\C-z" . slime-switch-to-output-buffer)
  836. ("\M-." . slime-edit-definition)))
  837. (add-to-list 'minor-mode-alist
  838. `(slime-popup-buffer-mode
  839. ,(if (featurep 'xemacs)
  840. 'slime-modeline-string
  841. '(:eval (unless slime-mode
  842. (slime-modeline-string))))))
  843. (set-keymap-parent slime-popup-buffer-mode-map slime-parent-map)
  844. (make-variable-buffer-local
  845. (defvar slime-popup-buffer-quit-function 'slime-popup-buffer-quit
  846. "The function that is used to quit a temporary popup buffer."))
  847. (defun slime-popup-buffer-quit-function (&optional kill-buffer-p)
  848. "Wrapper to invoke the value of `slime-popup-buffer-quit-function'."
  849. (interactive)
  850. (funcall slime-popup-buffer-quit-function kill-buffer-p))
  851. ;; Interface
  852. (defun slime-popup-buffer-quit (&optional kill-buffer-p)
  853. "Get rid of the current (temp) buffer without asking.
  854. Restore the window configuration unless it was changed since we
  855. last activated the buffer."
  856. (interactive)
  857. (let ((buffer (current-buffer)))
  858. (slime-close-popup-window)
  859. (when kill-buffer-p
  860. (kill-buffer buffer))))
  861. ;;;;; Filename translation
  862. ;;;
  863. ;;; Filenames passed between Emacs and Lisp should be translated using
  864. ;;; these functions. This way users who run Emacs and Lisp on separate
  865. ;;; machines have a chance to integrate file operations somehow.
  866. (defvar slime-to-lisp-filename-function #'convert-standard-filename
  867. "Function to translate Emacs filenames to CL namestrings.")
  868. (defvar slime-from-lisp-filename-function #'identity
  869. "Function to translate CL namestrings to Emacs filenames.")
  870. (defun slime-to-lisp-filename (filename)
  871. "Translate the string FILENAME to a Lisp filename."
  872. (funcall slime-to-lisp-filename-function filename))
  873. (defun slime-from-lisp-filename (filename)
  874. "Translate the Lisp filename FILENAME to an Emacs filename."
  875. (funcall slime-from-lisp-filename-function filename))
  876. ;;;; Starting SLIME
  877. ;;;
  878. ;;; This section covers starting an inferior-lisp, compiling and
  879. ;;; starting the server, initiating a network connection.
  880. ;;;;; Entry points
  881. ;; We no longer load inf-lisp, but we use this variable for backward
  882. ;; compatibility.
  883. (defvar inferior-lisp-program "lisp"
  884. "*Program name for invoking an inferior Lisp with for Inferior Lisp mode.")
  885. (defvar slime-lisp-implementations nil
  886. "*A list of known Lisp implementations.
  887. The list should have the form:
  888. ((NAME (PROGRAM PROGRAM-ARGS...) &key KEYWORD-ARGS) ...)
  889. NAME is a symbol for the implementation.
  890. PROGRAM and PROGRAM-ARGS are strings used to start the Lisp process.
  891. For KEYWORD-ARGS see `slime-start'.
  892. Here's an example:
  893. ((cmucl (\"/opt/cmucl/bin/lisp\" \"-quiet\") :init slime-init-command)
  894. (acl (\"acl7\") :coding-system emacs-mule))")
  895. (defvar slime-default-lisp nil
  896. "*The name of the default Lisp implementation.
  897. See `slime-lisp-implementations'")
  898. ;; dummy definitions for the compiler
  899. (defvar slime-net-processes)
  900. (defvar slime-default-connection)
  901. (defun slime (&optional command coding-system)
  902. "Start an inferior^_superior Lisp and connect to its Swank server."
  903. (interactive)
  904. (let ((inferior-lisp-program (or command inferior-lisp-program))
  905. (slime-net-coding-system (or coding-system slime-net-coding-system)))
  906. (slime-start* (cond ((and command (symbolp command))
  907. (slime-lisp-options command))
  908. (t (slime-read-interactive-args))))))
  909. (defvar slime-inferior-lisp-program-history '()
  910. "History list of command strings. Used by `slime'.")
  911. (defun slime-read-interactive-args ()
  912. "Return the list of args which should be passed to `slime-start'.
  913. The rules for selecting the arguments are rather complicated:
  914. - In the most common case, i.e. if there's no prefix-arg in
  915. effect and if `slime-lisp-implementations' is nil, use
  916. `inferior-lisp-program' as fallback.
  917. - If the table `slime-lisp-implementations' is non-nil use the
  918. implementation with name `slime-default-lisp' or if that's nil
  919. the first entry in the table.
  920. - If the prefix-arg is `-', prompt for one of the registered
  921. lisps.
  922. - If the prefix-arg is positive, read the command to start the
  923. process."
  924. (let ((table slime-lisp-implementations))
  925. (cond ((not current-prefix-arg) (slime-lisp-options))
  926. ((eq current-prefix-arg '-)
  927. (let ((key (completing-read
  928. "Lisp name: " (mapcar (lambda (x)
  929. (list (symbol-name (car x))))
  930. table)
  931. nil t)))
  932. (slime-lookup-lisp-implementation table (intern key))))
  933. (t
  934. (destructuring-bind (program &rest program-args)
  935. (split-string (read-string
  936. "Run lisp: " inferior-lisp-program
  937. 'slime-inferior-lisp-program-history))
  938. (let ((coding-system
  939. (if (eq 16 (prefix-numeric-value current-prefix-arg))
  940. (read-coding-system "set slime-coding-system: "
  941. slime-net-coding-system)
  942. slime-net-coding-system)))
  943. (list :program program :program-args program-args
  944. :coding-system coding-system)))))))
  945. (defun slime-lisp-options (&optional name)
  946. (let ((table slime-lisp-implementations))
  947. (assert (or (not name) table))
  948. (cond (table (slime-lookup-lisp-implementation slime-lisp-implementations
  949. (or name slime-default-lisp
  950. (car (car table)))))
  951. (t (destructuring-bind (program &rest args)
  952. (split-string inferior-lisp-program)
  953. (list :program program :program-args args))))))
  954. (defun slime-lookup-lisp-implementation (table name)
  955. (destructuring-bind (name (prog &rest args) &rest keys) (assoc name table)
  956. (list* :name name :program prog :program-args args keys)))
  957. (defun* slime-start (&key (program inferior-lisp-program) program-args
  958. directory
  959. (coding-system slime-net-coding-system)
  960. (init 'slime-init-command)
  961. name
  962. (buffer "*inferior-lisp*")
  963. init-function
  964. env)
  965. "Start a Lisp process and connect to it.
  966. This function is intended for programmatic use if `slime' is not
  967. flexible enough.
  968. PROGRAM and PROGRAM-ARGS are the filename and argument strings
  969. for the subprocess.
  970. INIT is a function that should return a string to load and start
  971. Swank. The function will be called with the PORT-FILENAME and ENCODING as
  972. arguments. INIT defaults to `slime-init-command'.
  973. CODING-SYSTEM a symbol for the coding system. The default is
  974. slime-net-coding-system
  975. ENV environment variables for the subprocess (see `process-environment').
  976. INIT-FUNCTION function to call right after the connection is established.
  977. BUFFER the name of the buffer to use for the subprocess.
  978. NAME a symbol to describe the Lisp implementation
  979. DIRECTORY change to this directory before starting the process.
  980. "
  981. (let ((args (list :program program :program-args program-args :buffer buffer
  982. :coding-system coding-system :init init :name name
  983. :init-function init-function :env env)))
  984. (slime-check-coding-system coding-system)
  985. (when (slime-bytecode-stale-p)
  986. (slime-urge-bytecode-recompile))
  987. (let ((proc (slime-maybe-start-lisp program program-args env
  988. directory buffer)))
  989. (slime-inferior-connect proc args)
  990. (pop-to-buffer (process-buffer proc)))))
  991. (defun slime-start* (options)
  992. (apply #'slime-start options))
  993. (defun slime-connect (host port &optional coding-system)
  994. "Connect to a running Swank server. Return the connection."
  995. (interactive (list (read-from-minibuffer "Host: " slime-lisp-host)
  996. (read-from-minibuffer "Port: " (format "%d" slime-port)
  997. nil t)))
  998. (when (and (interactive-p) slime-net-processes
  999. (y-or-n-p "Close old connections first? "))
  1000. (slime-disconnect-all))
  1001. (message "Connecting to Swank on port %S.." port)
  1002. (let ((coding-system (or coding-system slime-net-coding-system)))
  1003. (slime-check-coding-system coding-system)
  1004. (message "Connecting to Swank on port %S.." port)
  1005. (let* ((process (slime-net-connect host port coding-system))
  1006. (slime-dispatching-connection process))
  1007. (slime-setup-connection process))))
  1008. ;; FIXME: seems redundant
  1009. (defun slime-start-and-init (options fun)
  1010. (let* ((rest (plist-get options :init-function))
  1011. (init (cond (rest `(lambda () (funcall ',rest) (funcall ',fun)))
  1012. (t fun))))
  1013. (slime-start* (plist-put (copy-list options) :init-function init))))
  1014. ;;;;; Start inferior lisp
  1015. ;;;
  1016. ;;; Here is the protocol for starting SLIME:
  1017. ;;;
  1018. ;;; 0. Emacs recompiles/reloads slime.elc if it exists and is stale.
  1019. ;;; 1. Emacs starts an inferior Lisp process.
  1020. ;;; 2. Emacs tells Lisp (via stdio) to load and start Swank.
  1021. ;;; 3. Lisp recompiles the Swank if needed.
  1022. ;;; 4. Lisp starts the Swank server and writes its TCP port to a temp file.
  1023. ;;; 5. Emacs reads the temp file to get the port and then connects.
  1024. ;;; 6. Emacs prints a message of warm encouragement for the hacking ahead.
  1025. ;;;
  1026. ;;; Between steps 2-5 Emacs polls for the creation of the temp file so
  1027. ;;; that it can make the connection. This polling may continue for a
  1028. ;;; fair while if Swank needs recompilation.
  1029. (defvar slime-connect-retry-timer nil
  1030. "Timer object while waiting for an inferior-lisp to start.")
  1031. ;;; Recompiling bytecode:
  1032. (defun slime-bytecode-stale-p ()
  1033. "Return true if slime.elc is older than slime.el."
  1034. (when-let (libfile (locate-library "slime"))
  1035. (let* ((basename (file-name-sans-extension libfile))
  1036. (sourcefile (concat basename ".el"))
  1037. (bytefile (concat basename ".elc")))
  1038. (and (file-exists-p bytefile)
  1039. (file-newer-than-file-p sourcefile bytefile)))))
  1040. (defun slime-recompile-bytecode ()
  1041. "Recompile and reload slime.
  1042. Warning: don't use this in XEmacs, it seems to crash it!"
  1043. (interactive)
  1044. (let ((sourcefile (concat (file-name-sans-extension (locate-library "slime"))
  1045. ".el")))
  1046. (byte-compile-file sourcefile t)))
  1047. (defun slime-urge-bytecode-recompile ()
  1048. "Urge the user to recompile slime.elc.
  1049. Return true if we have been given permission to continue."
  1050. (cond ((featurep 'xemacs)
  1051. ;; My XEmacs crashes and burns if I recompile/reload an elisp
  1052. ;; file from itself. So they have to do it themself.
  1053. (or (y-or-n-p "slime.elc is older than source. Continue? ")
  1054. (signal 'quit nil)))
  1055. ((y-or-n-p "slime.elc is older than source. Recompile first? ")
  1056. (slime-recompile-bytecode))
  1057. (t)))
  1058. (defun slime-abort-connection ()
  1059. "Abort connection the current connection attempt."
  1060. (interactive)
  1061. (cond (slime-connect-retry-timer
  1062. (slime-cancel-connect-retry-timer)
  1063. (message "Cancelled connection attempt."))
  1064. (t (error "Not connecting"))))
  1065. ;;; Starting the inferior Lisp and loading Swank:
  1066. (defun slime-maybe-start-lisp (program program-args env directory buffer)
  1067. "Return a new or existing inferior lisp process."
  1068. (cond ((not (comint-check-proc buffer))
  1069. (slime-start-lisp program program-args env directory buffer))
  1070. ((slime-reinitialize-inferior-lisp-p program program-args env buffer)
  1071. (when-let (conn (find (get-buffer-process buffer) slime-net-processes
  1072. :key #'slime-inferior-process))
  1073. (slime-net-close conn))
  1074. (get-buffer-process buffer))
  1075. (t (slime-start-lisp program program-args env directory
  1076. (generate-new-buffer-name buffer)))))
  1077. (defun slime-reinitialize-inferior-lisp-p (program program-args env buffer)
  1078. (let ((args (slime-inferior-lisp-args (get-buffer-process buffer))))
  1079. (and (equal (plist-get args :program) program)
  1080. (equal (plist-get args :program-args) program-args)
  1081. (equal (plist-get args :env) env)
  1082. (not (y-or-n-p "Create an additional *inferior-lisp*? ")))))
  1083. (defvar slime-inferior-process-start-hook nil
  1084. "Hook called whenever a new process gets started.")
  1085. (defun slime-start-lisp (program program-args env directory buffer)
  1086. "Does the same as `inferior-lisp' but less ugly.
  1087. Return the created process."
  1088. (with-current-buffer (get-buffer-create buffer)
  1089. (when directory
  1090. (cd (expand-file-name directory)))
  1091. (comint-mode)
  1092. (let ((process-environment (append env process-environment))
  1093. (process-connection-type nil))
  1094. (comint-exec (current-buffer) "inferior-lisp" program nil program-args))
  1095. (lisp-mode-variables t)
  1096. (let ((proc (get-buffer-process (current-buffer))))
  1097. (slime-set-query-on-exit-flag proc)
  1098. (run-hooks 'slime-inferior-process-start-hook)
  1099. proc)))
  1100. (defun slime-inferior-connect (process args)
  1101. "Start a Swank server in the inferior Lisp and connect."
  1102. (slime-delete-swank-port-file 'quiet)
  1103. (slime-start-swank-server process args)
  1104. (slime-read-port-and-connect process nil))
  1105. (defvar slime-inferior-lisp-args nil
  1106. "A buffer local variable in the inferior proccess.
  1107. See `slime-start'.")
  1108. (defun slime-start-swank-server (process args)
  1109. "Start a Swank server on the inferior lisp."
  1110. (destructuring-bind (&key coding-system init &allow-other-keys) args
  1111. (with-current-buffer (process-buffer process)
  1112. (make-local-variable 'slime-inferior-lisp-args)
  1113. (setq slime-inferior-lisp-args args)
  1114. (let ((str (funcall init (slime-swank-port-file) coding-system)))
  1115. (goto-char (process-mark process))
  1116. (insert-before-markers str)
  1117. (process-send-string process str)))))
  1118. (defun slime-inferior-lisp-args (process)
  1119. "Return the initial process arguments.
  1120. See `slime-start'."
  1121. (with-current-buffer (process-buffer process)
  1122. slime-inferior-lisp-args))
  1123. ;; XXX load-server & start-server used to be separated. maybe that was better.
  1124. (defun slime-init-command (port-filename coding-system)
  1125. "Return a string to initialize Lisp."
  1126. (let ((loader (if (file-name-absolute-p slime-backend)
  1127. slime-backend
  1128. (concat slime-path slime-backend)))
  1129. (encoding (slime-coding-system-cl-name coding-system)))
  1130. ;; Return a single form to avoid problems with buffered input.
  1131. (format "%S\n\n"
  1132. `(progn
  1133. (load ,(slime-to-lisp-filename (expand-file-name loader))
  1134. :verbose t)
  1135. (funcall (read-from-string "swank-loader:init"))
  1136. (funcall (read-from-string "swank:start-server")
  1137. ,(slime-to-lisp-filename port-filename)
  1138. :coding-system ,encoding)))))
  1139. (defun slime-swank-port-file ()
  1140. "Filename where the SWANK server writes its TCP port number."
  1141. (concat (file-name-as-directory (slime-temp-directory))
  1142. (format "slime.%S" (ema…

Large files files are truncated, but you can click here to view the full file