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.

172 lines
5.9 KiB

4 years ago
  1. (require 'slime)
  2. (require 'slime-repl)
  3. (require 'cl-lib)
  4. (eval-when-compile
  5. (require 'cl)) ; lexical-let
  6. (define-slime-contrib slime-clipboard
  7. "This add a few commands to put objects into a clipboard and to
  8. insert textual references to those objects.
  9. The clipboard command prefix is C-c @.
  10. C-c @ + adds an object to the clipboard
  11. C-c @ @ inserts a reference to an object in the clipboard
  12. C-c @ ? displays the clipboard
  13. This package also also binds the + key in the inspector and
  14. debugger to add the object at point to the clipboard."
  15. (:authors "Helmut Eller <heller@common-lisp.net>")
  16. (:license "GPL")
  17. (:swank-dependencies swank-clipboard))
  18. (define-derived-mode slime-clipboard-mode fundamental-mode
  19. "Slime-Clipboard"
  20. "SLIME Clipboad Mode.
  21. \\{slime-clipboard-mode-map}")
  22. (slime-define-keys slime-clipboard-mode-map
  23. ("g" 'slime-clipboard-redisplay)
  24. ((kbd "C-k") 'slime-clipboard-delete-entry)
  25. ("i" 'slime-clipboard-inspect))
  26. (defvar slime-clipboard-map (make-sparse-keymap))
  27. (slime-define-keys slime-clipboard-map
  28. ("?" 'slime-clipboard-display)
  29. ("+" 'slime-clipboard-add)
  30. ("@" 'slime-clipboard-ref))
  31. (define-key slime-mode-map (kbd "C-c @") slime-clipboard-map)
  32. (define-key slime-repl-mode-map (kbd "C-c @") slime-clipboard-map)
  33. (slime-define-keys slime-inspector-mode-map
  34. ("+" 'slime-clipboard-add-from-inspector))
  35. (slime-define-keys sldb-mode-map
  36. ("+" 'slime-clipboard-add-from-sldb))
  37. (defun slime-clipboard-add (exp package)
  38. "Add an object to the clipboard."
  39. (interactive (list (slime-read-from-minibuffer
  40. "Add to clipboard (evaluated): "
  41. (slime-sexp-at-point))
  42. (slime-current-package)))
  43. (slime-clipboard-add-internal `(:string ,exp ,package)))
  44. (defun slime-clipboard-add-internal (datum)
  45. (slime-eval-async `(swank-clipboard:add ',datum)
  46. (lambda (result) (message "%s" result))))
  47. (defun slime-clipboard-display ()
  48. "Display the content of the clipboard."
  49. (interactive)
  50. (slime-eval-async `(swank-clipboard:entries)
  51. #'slime-clipboard-display-entries))
  52. (defun slime-clipboard-display-entries (entries)
  53. (slime-with-popup-buffer ((slime-buffer-name :clipboard)
  54. :mode 'slime-clipboard-mode)
  55. (slime-clipboard-insert-entries entries)))
  56. (defun slime-clipboard-insert-entries (entries)
  57. (let ((fstring "%2s %3s %s\n"))
  58. (insert (format fstring "Nr" "Id" "Value")
  59. (format fstring "--" "--" "-----" ))
  60. (save-excursion
  61. (cl-loop for i from 0 for (ref . value) in entries do
  62. (slime-insert-propertized `(slime-clipboard-entry ,i
  63. slime-clipboard-ref ,ref)
  64. (format fstring i ref value))))))
  65. (defun slime-clipboard-redisplay ()
  66. "Update the clipboard buffer."
  67. (interactive)
  68. (lexical-let ((saved (point)))
  69. (slime-eval-async
  70. `(swank-clipboard:entries)
  71. (lambda (entries)
  72. (let ((inhibit-read-only t))
  73. (erase-buffer)
  74. (slime-clipboard-insert-entries entries)
  75. (when (< saved (point-max))
  76. (goto-char saved)))))))
  77. (defun slime-clipboard-entry-at-point ()
  78. (or (get-text-property (point) 'slime-clipboard-entry)
  79. (error "No clipboard entry at point")))
  80. (defun slime-clipboard-ref-at-point ()
  81. (or (get-text-property (point) 'slime-clipboard-ref)
  82. (error "No clipboard ref at point")))
  83. (defun slime-clipboard-inspect (&optional entry)
  84. "Inspect the current clipboard entry."
  85. (interactive (list (slime-clipboard-ref-at-point)))
  86. (slime-inspect (prin1-to-string `(swank-clipboard::clipboard-ref ,entry))))
  87. (defun slime-clipboard-delete-entry (&optional entry)
  88. "Delete the current entry from the clipboard."
  89. (interactive (list (slime-clipboard-entry-at-point)))
  90. (slime-eval-async `(swank-clipboard:delete-entry ,entry)
  91. (lambda (result)
  92. (slime-clipboard-redisplay)
  93. (message "%s" result))))
  94. (defun slime-clipboard-ref ()
  95. "Ask for a clipboard entry number and insert a reference to it."
  96. (interactive)
  97. (slime-clipboard-read-entry-number #'slime-clipboard-insert-ref))
  98. ;; insert a reference to clipboard entry ENTRY at point. The text
  99. ;; receives a special 'display property to make it look nicer. We
  100. ;; remove this property in a modification when a user tries to modify
  101. ;; he real text.
  102. (defun slime-clipboard-insert-ref (entry)
  103. (cl-destructuring-bind (ref . string)
  104. (slime-eval `(swank-clipboard:entry-to-ref ,entry))
  105. (slime-insert-propertized
  106. `(display ,(format "#@%d%s" ref string)
  107. modification-hooks (slime-clipboard-ref-modified)
  108. rear-nonsticky t)
  109. (format "(swank-clipboard::clipboard-ref %d)" ref))))
  110. (defun slime-clipboard-ref-modified (start end)
  111. (when (get-text-property start 'display)
  112. (let ((inhibit-modification-hooks t))
  113. (save-excursion
  114. (goto-char start)
  115. (cl-destructuring-bind (dstart dend) (slime-property-bounds 'display)
  116. (unless (and (= start dstart) (= end dend))
  117. (remove-list-of-text-properties
  118. dstart dend '(display modification-hooks))))))))
  119. ;; Read a entry number.
  120. ;; Written in CPS because the display the clipboard before reading.
  121. (defun slime-clipboard-read-entry-number (k)
  122. (slime-eval-async
  123. `(swank-clipboard:entries)
  124. (slime-rcurry
  125. (lambda (entries window-config k)
  126. (slime-clipboard-display-entries entries)
  127. (let ((entry (unwind-protect
  128. (read-from-minibuffer "Entry number: " nil nil t)
  129. (set-window-configuration window-config))))
  130. (funcall k entry)))
  131. (current-window-configuration)
  132. k)))
  133. (defun slime-clipboard-add-from-inspector ()
  134. (interactive)
  135. (let ((part (or (get-text-property (point) 'slime-part-number)
  136. (error "No part at point"))))
  137. (slime-clipboard-add-internal `(:inspector ,part))))
  138. (defun slime-clipboard-add-from-sldb ()
  139. (interactive)
  140. (slime-clipboard-add-internal
  141. `(:sldb ,(sldb-frame-number-at-point)
  142. ,(sldb-var-number-at-point))))
  143. (provide 'slime-clipboard)