Klimi's new dotfiles with stow.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

700 line
25 KiB

4 年之前
  1. ;;;;; -*- indent-tabs-mode: nil -*-
  2. ;;;
  3. ;;; swank-mezzano.lisp --- SLIME backend for Mezzano
  4. ;;;
  5. ;;; This code has been placed in the Public Domain. All warranties are
  6. ;;; disclaimed.
  7. ;;;
  8. ;;; Administrivia
  9. (defpackage swank/mezzano
  10. (:use cl swank/backend))
  11. (in-package swank/mezzano)
  12. ;;; swank-mop
  13. (import-swank-mop-symbols :mezzano.clos '(:class-default-initargs
  14. :class-direct-default-initargs
  15. :specializer-direct-methods
  16. :generic-function-declarations))
  17. (defun swank-mop:specializer-direct-methods (obj)
  18. (declare (ignore obj))
  19. '())
  20. (defun swank-mop:generic-function-declarations (gf)
  21. (declare (ignore gf))
  22. '())
  23. (defimplementation gray-package-name ()
  24. "MEZZANO.GRAY")
  25. ;;;; TCP server
  26. (defclass listen-socket ()
  27. ((%listener :initarg :listener)))
  28. (defimplementation create-socket (host port &key backlog)
  29. (make-instance 'listen-socket
  30. :listener (mezzano.network.tcp:tcp-listen
  31. host
  32. port
  33. :backlog (or backlog 10))))
  34. (defimplementation local-port (socket)
  35. (mezzano.network.tcp:tcp-listener-local-port (slot-value socket '%listener)))
  36. (defimplementation close-socket (socket)
  37. (mezzano.network.tcp:close-tcp-listener (slot-value socket '%listener)))
  38. (defimplementation accept-connection (socket &key external-format
  39. buffering timeout)
  40. (declare (ignore external-format buffering timeout))
  41. (loop
  42. (let ((value (mezzano.network.tcp:tcp-accept (slot-value socket '%listener)
  43. :wait-p nil)))
  44. (if value
  45. (return value)
  46. ;; Poke standard-input every now and then to keep the console alive.
  47. (progn (listen)
  48. (sleep 0.05))))))
  49. (defimplementation preferred-communication-style ()
  50. :spawn)
  51. ;;;; Unix signals
  52. ;;;; ????
  53. (defimplementation getpid ()
  54. 0)
  55. ;;;; Compilation
  56. (defun signal-compiler-condition (condition severity)
  57. (signal 'compiler-condition
  58. :original-condition condition
  59. :severity severity
  60. :message (format nil "~A" condition)
  61. :location nil))
  62. (defimplementation call-with-compilation-hooks (func)
  63. (handler-bind
  64. ((error
  65. (lambda (c)
  66. (signal-compiler-condition c :error)))
  67. (warning
  68. (lambda (c)
  69. (signal-compiler-condition c :warning)))
  70. (style-warning
  71. (lambda (c)
  72. (signal-compiler-condition c :style-warning))))
  73. (funcall func)))
  74. (defimplementation swank-compile-string (string &key buffer position filename
  75. policy)
  76. (declare (ignore buffer policy))
  77. (let* ((*load-pathname* (ignore-errors (pathname filename)))
  78. (*load-truename* (when *load-pathname*
  79. (ignore-errors (truename *load-pathname*))))
  80. (sys.int::*top-level-form-number* `(:position ,position)))
  81. (with-compilation-hooks ()
  82. (eval (read-from-string (concatenate 'string "(progn " string " )")))))
  83. t)
  84. (defimplementation swank-compile-file (input-file output-file load-p
  85. external-format
  86. &key policy)
  87. (with-compilation-hooks ()
  88. (multiple-value-prog1
  89. (compile-file input-file
  90. :output-file output-file
  91. :external-format external-format)
  92. (when load-p
  93. (load output-file)))))
  94. (defimplementation find-external-format (coding-system)
  95. (if (or (equal coding-system "utf-8")
  96. (equal coding-system "utf-8-unix"))
  97. :default
  98. nil))
  99. ;;;; Debugging
  100. ;; Definitely don't allow this.
  101. (defimplementation install-debugger-globally (function)
  102. (declare (ignore function))
  103. nil)
  104. (defvar *current-backtrace*)
  105. (defimplementation call-with-debugging-environment (debugger-loop-fn)
  106. (let ((*current-backtrace* '()))
  107. (let ((prev-fp nil))
  108. (sys.int::map-backtrace
  109. (lambda (i fp)
  110. (push (list (1- i) fp prev-fp) *current-backtrace*)
  111. (setf prev-fp fp))))
  112. (setf *current-backtrace* (reverse *current-backtrace*))
  113. ;; Drop the topmost frame, which is finished call to MAP-BACKTRACE.
  114. (pop *current-backtrace*)
  115. ;; And the next one for good measure.
  116. (pop *current-backtrace*)
  117. (funcall debugger-loop-fn)))
  118. (defimplementation compute-backtrace (start end)
  119. (subseq *current-backtrace* start end))
  120. (defimplementation print-frame (frame stream)
  121. (format stream "~S" (sys.int::function-from-frame frame)))
  122. (defimplementation frame-source-location (frame-number)
  123. (let* ((frame (nth frame-number *current-backtrace*))
  124. (fn (sys.int::function-from-frame frame)))
  125. (function-location fn)))
  126. (defimplementation frame-locals (frame-number)
  127. (loop
  128. with frame = (nth frame-number *current-backtrace*)
  129. for (name id location repr) in (sys.int::frame-locals frame)
  130. collect (list :name name
  131. :id id
  132. :value (sys.int::read-frame-slot frame location repr))))
  133. (defimplementation frame-var-value (frame-number var-id)
  134. (let* ((frame (nth frame-number *current-backtrace*))
  135. (locals (sys.int::frame-locals frame))
  136. (info (nth var-id locals)))
  137. (if info
  138. (destructuring-bind (name id location repr)
  139. info
  140. (declare (ignore id))
  141. (values (sys.int::read-frame-slot frame location repr) name))
  142. (error "Invalid variable id ~D for frame number ~D."
  143. var-id frame-number))))
  144. ;;;; Definition finding
  145. (defun top-level-form-position (pathname tlf)
  146. (ignore-errors
  147. (with-open-file (s pathname)
  148. (loop
  149. repeat tlf
  150. do (with-standard-io-syntax
  151. (let ((*read-suppress* t)
  152. (*read-eval* nil))
  153. (read s nil))))
  154. (let ((default (make-pathname :host (pathname-host s))))
  155. (make-location `(:file ,(enough-namestring s default))
  156. `(:position ,(1+ (file-position s))))))))
  157. (defun function-location (function)
  158. "Return a location object for FUNCTION."
  159. (let* ((info (sys.int::function-debug-info function))
  160. (pathname (sys.int::debug-info-source-pathname info))
  161. (tlf (sys.int::debug-info-source-top-level-form-number info)))
  162. (cond ((and (consp tlf)
  163. (eql (first tlf) :position))
  164. (let ((default (make-pathname :host (pathname-host pathname))))
  165. (make-location `(:file ,(enough-namestring pathname default))
  166. `(:position ,(second tlf)))))
  167. (t
  168. (top-level-form-position pathname tlf)))))
  169. (defun method-definition-name (name method)
  170. `(defmethod ,name
  171. ,@(mezzano.clos:method-qualifiers method)
  172. ,(mapcar (lambda (x)
  173. (typecase x
  174. (mezzano.clos:class
  175. (mezzano.clos:class-name x))
  176. (mezzano.clos:eql-specializer
  177. `(eql ,(mezzano.clos:eql-specializer-object x)))
  178. (t x)))
  179. (mezzano.clos:method-specializers method))))
  180. (defimplementation find-definitions (name)
  181. (let ((result '()))
  182. (labels
  183. ((frob-fn (dspec fn)
  184. (let ((loc (function-location fn)))
  185. (when loc
  186. (push (list dspec loc) result))))
  187. (try-fn (name)
  188. (when (valid-function-name-p name)
  189. (when (and (fboundp name)
  190. (not (and (symbolp name)
  191. (or (special-operator-p name)
  192. (macro-function name)))))
  193. (let ((fn (fdefinition name)))
  194. (cond ((typep fn 'mezzano.clos:standard-generic-function)
  195. (dolist (m (mezzano.clos:generic-function-methods fn))
  196. (frob-fn (method-definition-name name m)
  197. (mezzano.clos:method-function m))))
  198. (t
  199. (frob-fn `(defun ,name) fn)))))
  200. (when (compiler-macro-function name)
  201. (frob-fn `(define-compiler-macro ,name)
  202. (compiler-macro-function name))))))
  203. (try-fn name)
  204. (try-fn `(setf name))
  205. (try-fn `(sys.int::cas name))
  206. (when (and (symbolp name)
  207. (get name 'sys.int::setf-expander))
  208. (frob-fn `(define-setf-expander ,name)
  209. (get name 'sys.int::setf-expander)))
  210. (when (and (symbolp name)
  211. (macro-function name))
  212. (frob-fn `(defmacro ,name)
  213. (macro-function name))))
  214. result))
  215. ;;;; XREF
  216. ;;; Simpler variants.
  217. (defun find-all-frefs ()
  218. (let ((frefs (make-array 500 :adjustable t :fill-pointer 0))
  219. (keep-going t))
  220. (loop
  221. (when (not keep-going)
  222. (return))
  223. (adjust-array frefs (* (array-dimension frefs 0) 2))
  224. (setf keep-going nil
  225. (fill-pointer frefs) 0)
  226. ;; Walk the wired area looking for FREFs.
  227. (sys.int::walk-area
  228. :wired
  229. (lambda (object address size)
  230. (when (sys.int::function-reference-p object)
  231. (when (not (vector-push object frefs))
  232. (setf keep-going t))))))
  233. (remove-duplicates (coerce frefs 'list))))
  234. (defimplementation list-callers (function-name)
  235. (let ((fref-for-fn (sys.int::function-reference function-name))
  236. (callers '()))
  237. (loop
  238. for fref in (find-all-frefs)
  239. for fn = (sys.int::function-reference-function fref)
  240. for name = (sys.int::function-reference-name fref)
  241. when fn
  242. do
  243. (cond ((typep fn 'standard-generic-function)
  244. (dolist (m (mezzano.clos:generic-function-methods fn))
  245. (let* ((mf (mezzano.clos:method-function m))
  246. (mf-frefs (get-all-frefs-in-function mf)))
  247. (when (member fref-for-fn mf-frefs)
  248. (push `((defmethod ,name
  249. ,@(mezzano.clos:method-qualifiers m)
  250. ,(mapcar #'specializer-name
  251. (mezzano.clos:method-specializers m)))
  252. ,(function-location mf))
  253. callers)))))
  254. ((member fref-for-fn
  255. (get-all-frefs-in-function fn))
  256. (push `((defun ,name) ,(function-location fn)) callers))))
  257. callers))
  258. (defun specializer-name (specializer)
  259. (if (typep specializer 'standard-class)
  260. (mezzano.clos:class-name specializer)
  261. specializer))
  262. (defun get-all-frefs-in-function (function)
  263. (when (sys.int::funcallable-std-instance-p function)
  264. (setf function (sys.int::funcallable-std-instance-function function)))
  265. (when (sys.int::closure-p function)
  266. (setf function (sys.int::%closure-function function)))
  267. (loop
  268. for i below (sys.int::function-pool-size function)
  269. for entry = (sys.int::function-pool-object function i)
  270. when (sys.int::function-reference-p entry)
  271. collect entry
  272. when (compiled-function-p entry) ; closures
  273. append (get-all-frefs-in-function entry)))
  274. (defimplementation list-callees (function-name)
  275. (let* ((fn (fdefinition function-name))
  276. ;; Grovel around in the function's constant pool looking for
  277. ;; function-references. These may be for #', but they're
  278. ;; probably going to be for normal calls.
  279. ;; TODO: This doesn't work well on interpreted functions or
  280. ;; funcallable instances.
  281. (callees (remove-duplicates (get-all-frefs-in-function fn))))
  282. (loop
  283. for fref in callees
  284. for name = (sys.int::function-reference-name fref)
  285. for fn = (sys.int::function-reference-function fref)
  286. when fn
  287. collect `((defun ,name) ,(function-location fn)))))
  288. ;;;; Documentation
  289. (defimplementation arglist (name)
  290. (let ((macro (when (symbolp name)
  291. (macro-function name)))
  292. (fn (if (functionp name)
  293. name
  294. (ignore-errors (fdefinition name)))))
  295. (cond
  296. (macro
  297. (get name 'sys.int::macro-lambda-list))
  298. (fn
  299. (cond
  300. ((typep fn 'mezzano.clos:standard-generic-function)
  301. (mezzano.clos:generic-function-lambda-list fn))
  302. (t
  303. (function-lambda-list fn))))
  304. (t :not-available))))
  305. (defun function-lambda-list (function)
  306. (sys.int::debug-info-lambda-list
  307. (sys.int::function-debug-info function)))
  308. (defimplementation type-specifier-p (symbol)
  309. (cond
  310. ((or (get symbol 'sys.int::type-expander)
  311. (get symbol 'sys.int::compound-type)
  312. (get symbol 'sys.int::type-symbol))
  313. t)
  314. (t :not-available)))
  315. (defimplementation function-name (function)
  316. (sys.int::function-name function))
  317. (defimplementation valid-function-name-p (form)
  318. "Is FORM syntactically valid to name a function?
  319. If true, FBOUNDP should not signal a type-error for FORM."
  320. (flet ((length=2 (list)
  321. (and (not (null (cdr list))) (null (cddr list)))))
  322. (or (symbolp form)
  323. (and (consp form) (length=2 form)
  324. (or (eq (first form) 'setf)
  325. (eq (first form) 'sys.int::cas))
  326. (symbolp (second form))))))
  327. (defimplementation describe-symbol-for-emacs (symbol)
  328. (let ((result '()))
  329. (when (boundp symbol)
  330. (setf (getf result :variable) nil))
  331. (when (and (fboundp symbol)
  332. (not (macro-function symbol)))
  333. (setf (getf result :function)
  334. (function-docstring symbol)))
  335. (when (fboundp `(setf ,symbol))
  336. (setf (getf result :setf)
  337. (function-docstring `(setf ,symbol))))
  338. (when (get symbol 'sys.int::setf-expander)
  339. (setf (getf result :setf) nil))
  340. (when (special-operator-p symbol)
  341. (setf (getf result :special-operator) nil))
  342. (when (macro-function symbol)
  343. (setf (getf result :macro) nil))
  344. (when (compiler-macro-function symbol)
  345. (setf (getf result :compiler-macro) nil))
  346. (when (type-specifier-p symbol)
  347. (setf (getf result :type) nil))
  348. (when (find-class symbol nil)
  349. (setf (getf result :class) nil))
  350. result))
  351. (defun function-docstring (function-name)
  352. (let* ((definition (fdefinition function-name))
  353. (debug-info (sys.int::function-debug-info definition)))
  354. (sys.int::debug-info-docstring debug-info)))
  355. ;;;; Multithreading
  356. ;; FIXME: This should be a weak table.
  357. (defvar *thread-ids-for-emacs* (make-hash-table))
  358. (defvar *next-thread-id-for-emacs* 0)
  359. (defvar *thread-id-for-emacs-lock* (mezzano.supervisor:make-mutex
  360. "SWANK thread ID table"))
  361. (defimplementation spawn (fn &key name)
  362. (mezzano.supervisor:make-thread fn :name name))
  363. (defimplementation thread-id (thread)
  364. (mezzano.supervisor:with-mutex (*thread-id-for-emacs-lock*)
  365. (let ((id (gethash thread *thread-ids-for-emacs*)))
  366. (when (null id)
  367. (setf id (incf *next-thread-id-for-emacs*)
  368. (gethash thread *thread-ids-for-emacs*) id
  369. (gethash id *thread-ids-for-emacs*) thread))
  370. id)))
  371. (defimplementation find-thread (id)
  372. (mezzano.supervisor:with-mutex (*thread-id-for-emacs-lock*)
  373. (gethash id *thread-ids-for-emacs*)))
  374. (defimplementation thread-name (thread)
  375. (mezzano.supervisor:thread-name thread))
  376. (defimplementation thread-status (thread)
  377. (format nil "~:(~A~)" (mezzano.supervisor:thread-state thread)))
  378. (defimplementation current-thread ()
  379. (mezzano.supervisor:current-thread))
  380. (defimplementation all-threads ()
  381. (mezzano.supervisor:all-threads))
  382. (defimplementation thread-alive-p (thread)
  383. (not (eql (mezzano.supervisor:thread-state thread) :dead)))
  384. (defimplementation interrupt-thread (thread fn)
  385. (mezzano.supervisor:establish-thread-foothold thread fn))
  386. (defimplementation kill-thread (thread)
  387. ;; Documentation says not to execute unwind-protected sections, but there's
  388. ;; no way to do that.
  389. ;; And killing threads at arbitrary points without unwinding them is a good
  390. ;; way to hose the system.
  391. (mezzano.supervisor:terminate-thread thread))
  392. (defvar *mailbox-lock* (mezzano.supervisor:make-mutex "mailbox lock"))
  393. (defvar *mailboxes* (list))
  394. (defstruct (mailbox (:conc-name mailbox.))
  395. thread
  396. (mutex (mezzano.supervisor:make-mutex))
  397. (queue '() :type list))
  398. (defun mailbox (thread)
  399. "Return THREAD's mailbox."
  400. ;; Use weak pointers to avoid holding on to dead threads forever.
  401. (mezzano.supervisor:with-mutex (*mailbox-lock*)
  402. ;; Flush forgotten threads.
  403. (setf *mailboxes*
  404. (remove-if-not #'sys.int::weak-pointer-value *mailboxes*))
  405. (loop
  406. for entry in *mailboxes*
  407. do
  408. (multiple-value-bind (key value livep)
  409. (sys.int::weak-pointer-pair entry)
  410. (when (eql key thread)
  411. (return value)))
  412. finally
  413. (let ((mb (make-mailbox :thread thread)))
  414. (push (sys.int::make-weak-pointer thread mb) *mailboxes*)
  415. (return mb)))))
  416. (defimplementation send (thread message)
  417. (let* ((mbox (mailbox thread))
  418. (mutex (mailbox.mutex mbox)))
  419. (mezzano.supervisor:with-mutex (mutex)
  420. (setf (mailbox.queue mbox)
  421. (nconc (mailbox.queue mbox) (list message))))))
  422. (defvar *receive-if-sleep-time* 0.02)
  423. (defimplementation receive-if (test &optional timeout)
  424. (let* ((mbox (mailbox (current-thread)))
  425. (mutex (mailbox.mutex mbox)))
  426. (assert (or (not timeout) (eq timeout t)))
  427. (loop
  428. (check-slime-interrupts)
  429. (mezzano.supervisor:with-mutex (mutex)
  430. (let* ((q (mailbox.queue mbox))
  431. (tail (member-if test q)))
  432. (when tail
  433. (setf (mailbox.queue mbox) (nconc (ldiff q tail) (cdr tail)))
  434. (return (car tail))))
  435. (when (eq timeout t) (return (values nil t))))
  436. (sleep *receive-if-sleep-time*))))
  437. (defvar *registered-threads* (make-hash-table))
  438. (defvar *registered-threads-lock*
  439. (mezzano.supervisor:make-mutex "registered threads lock"))
  440. (defimplementation register-thread (name thread)
  441. (declare (type symbol name))
  442. (mezzano.supervisor:with-mutex (*registered-threads-lock*)
  443. (etypecase thread
  444. (null
  445. (remhash name *registered-threads*))
  446. (mezzano.supervisor:thread
  447. (setf (gethash name *registered-threads*) thread))))
  448. nil)
  449. (defimplementation find-registered (name)
  450. (mezzano.supervisor:with-mutex (*registered-threads-lock*)
  451. (values (gethash name *registered-threads*))))
  452. (defimplementation wait-for-input (streams &optional timeout)
  453. (loop
  454. (let ((ready '()))
  455. (dolist (s streams)
  456. (when (or (listen s)
  457. (and (typep s 'mezzano.network.tcp::tcp-stream)
  458. (mezzano.network.tcp::tcp-connection-closed-p s)))
  459. (push s ready)))
  460. (when ready
  461. (return ready))
  462. (when (check-slime-interrupts)
  463. (return :interrupt))
  464. (when timeout
  465. (return '()))
  466. (sleep 1)
  467. (when (numberp timeout)
  468. (decf timeout 1)
  469. (when (not (plusp timeout))
  470. (return '()))))))
  471. ;;;; Locks
  472. (defstruct recursive-lock
  473. mutex
  474. (depth 0))
  475. (defimplementation make-lock (&key name)
  476. (make-recursive-lock
  477. :mutex (mezzano.supervisor:make-mutex name)))
  478. (defimplementation call-with-lock-held (lock function)
  479. (cond ((mezzano.supervisor:mutex-held-p
  480. (recursive-lock-mutex lock))
  481. (unwind-protect
  482. (progn (incf (recursive-lock-depth lock))
  483. (funcall function))
  484. (decf (recursive-lock-depth lock))))
  485. (t
  486. (mezzano.supervisor:with-mutex ((recursive-lock-mutex lock))
  487. (multiple-value-prog1
  488. (funcall function)
  489. (assert (eql (recursive-lock-depth lock) 0)))))))
  490. ;;;; Character names
  491. (defimplementation character-completion-set (prefix matchp)
  492. ;; TODO: Unicode characters too.
  493. (loop
  494. for names in sys.int::*char-name-alist*
  495. append
  496. (loop
  497. for name in (rest names)
  498. when (funcall matchp prefix name)
  499. collect name)))
  500. ;;;; Inspector
  501. (defmethod emacs-inspect ((o function))
  502. (case (sys.int::%object-tag o)
  503. (#.sys.int::+object-tag-function+
  504. (label-value-line*
  505. (:name (sys.int::function-name o))
  506. (:arglist (arglist o))
  507. (:debug-info (sys.int::function-debug-info o))))
  508. (#.sys.int::+object-tag-closure+
  509. (append
  510. (label-value-line :function (sys.int::%closure-function o))
  511. `("Closed over values:" (:newline))
  512. (loop
  513. for i below (sys.int::%closure-length o)
  514. append (label-value-line i (sys.int::%closure-value o i)))))
  515. (t
  516. (call-next-method))))
  517. (defmethod emacs-inspect ((o sys.int::weak-pointer))
  518. (label-value-line*
  519. (:key (sys.int::weak-pointer-key o))
  520. (:value (sys.int::weak-pointer-value o))))
  521. (defmethod emacs-inspect ((o sys.int::function-reference))
  522. (label-value-line*
  523. (:name (sys.int::function-reference-name o))
  524. (:function (sys.int::function-reference-function o))))
  525. (defmethod emacs-inspect ((object structure-object))
  526. (let ((class (class-of object)))
  527. `("Class: " (:value ,class) (:newline)
  528. ,@(swank::all-slots-for-inspector object))))
  529. (in-package :swank)
  530. (defmethod all-slots-for-inspector ((object structure-object))
  531. (let* ((class (class-of object))
  532. (direct-slots (swank-mop:class-direct-slots class))
  533. (effective-slots (swank-mop:class-slots class))
  534. (longest-slot-name-length
  535. (loop for slot :in effective-slots
  536. maximize (length (symbol-name
  537. (swank-mop:slot-definition-name slot)))))
  538. (checklist
  539. (reinitialize-checklist
  540. (ensure-istate-metadata object :checklist
  541. (make-checklist (length effective-slots)))))
  542. (grouping-kind
  543. ;; We box the value so we can re-set it.
  544. (ensure-istate-metadata object :grouping-kind
  545. (box *inspector-slots-default-grouping*)))
  546. (sort-order
  547. (ensure-istate-metadata object :sort-order
  548. (box *inspector-slots-default-order*)))
  549. (sort-predicate (ecase (ref sort-order)
  550. (:alphabetically #'string<)
  551. (:unsorted (constantly nil))))
  552. (sorted-slots (sort (copy-seq effective-slots)
  553. sort-predicate
  554. :key #'swank-mop:slot-definition-name))
  555. (effective-slots
  556. (ecase (ref grouping-kind)
  557. (:all sorted-slots)
  558. (:inheritance (stable-sort-by-inheritance sorted-slots
  559. class sort-predicate)))))
  560. `("--------------------"
  561. (:newline)
  562. " Group slots by inheritance "
  563. (:action ,(ecase (ref grouping-kind)
  564. (:all "[ ]")
  565. (:inheritance "[X]"))
  566. ,(lambda ()
  567. ;; We have to do this as the order of slots will
  568. ;; be sorted differently.
  569. (fill (checklist.buttons checklist) nil)
  570. (setf (ref grouping-kind)
  571. (ecase (ref grouping-kind)
  572. (:all :inheritance)
  573. (:inheritance :all))))
  574. :refreshp t)
  575. (:newline)
  576. " Sort slots alphabetically "
  577. (:action ,(ecase (ref sort-order)
  578. (:unsorted "[ ]")
  579. (:alphabetically "[X]"))
  580. ,(lambda ()
  581. (fill (checklist.buttons checklist) nil)
  582. (setf (ref sort-order)
  583. (ecase (ref sort-order)
  584. (:unsorted :alphabetically)
  585. (:alphabetically :unsorted))))
  586. :refreshp t)
  587. (:newline)
  588. ,@ (case (ref grouping-kind)
  589. (:all
  590. `((:newline)
  591. "All Slots:"
  592. (:newline)
  593. ,@(make-slot-listing checklist object class
  594. effective-slots direct-slots
  595. longest-slot-name-length)))
  596. (:inheritance
  597. (list-all-slots-by-inheritance checklist object class
  598. effective-slots direct-slots
  599. longest-slot-name-length)))
  600. (:newline)
  601. (:action "[set value]"
  602. ,(lambda ()
  603. (do-checklist (idx checklist)
  604. (query-and-set-slot class object
  605. (nth idx effective-slots))))
  606. :refreshp t)
  607. " "
  608. (:action "[make unbound]"
  609. ,(lambda ()
  610. (do-checklist (idx checklist)
  611. (swank-mop:slot-makunbound-using-class
  612. class object (nth idx effective-slots))))
  613. :refreshp t)
  614. (:newline))))