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.

204 lines
8.1 KiB

4 years ago
  1. ;;; helm-eval.el --- eval expressions from helm. -*- lexical-binding: t -*-
  2. ;; Copyright (C) 2012 ~ 2019 Thierry Volpiatto <thierry.volpiatto@gmail.com>
  3. ;; This program is free software; you can redistribute it and/or modify
  4. ;; it under the terms of the GNU General Public License as published by
  5. ;; the Free Software Foundation, either version 3 of the License, or
  6. ;; (at your option) any later version.
  7. ;; This program is distributed in the hope that it will be useful,
  8. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. ;; GNU General Public License for more details.
  11. ;; You should have received a copy of the GNU General Public License
  12. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ;;; Code:
  14. (require 'cl-lib)
  15. (require 'helm)
  16. (require 'helm-help)
  17. (require 'eldoc)
  18. (require 'edebug)
  19. (defgroup helm-eval nil
  20. "Eval related Applications and libraries for Helm."
  21. :group 'helm)
  22. (defcustom helm-eldoc-in-minibuffer-show-fn
  23. 'helm-show-info-in-mode-line
  24. "A function to display eldoc info.
  25. Should take one arg: the string to display."
  26. :group 'helm-eval
  27. :type 'symbol)
  28. (defcustom helm-show-info-in-mode-line-delay 12
  29. "Eldoc will show info in mode-line during this delay if user is idle."
  30. :type 'integer
  31. :group 'helm-eval)
  32. ;;; Eldoc compatibility between emacs-24 and emacs-25
  33. ;;
  34. (if (require 'elisp-mode nil t) ; emacs-25
  35. ;; Maybe the eldoc functions have been
  36. ;; already aliased by eldoc-eval.
  37. (cl-loop for (f . a) in '((eldoc-current-symbol .
  38. elisp--current-symbol)
  39. (eldoc-fnsym-in-current-sexp .
  40. elisp--fnsym-in-current-sexp)
  41. (eldoc-get-fnsym-args-string .
  42. elisp-get-fnsym-args-string)
  43. (eldoc-get-var-docstring .
  44. elisp-get-var-docstring))
  45. unless (fboundp f)
  46. do (defalias f a))
  47. ;; Emacs-24.
  48. (declare-function eldoc-current-symbol "eldoc")
  49. (declare-function eldoc-get-fnsym-args-string "eldoc" (sym &optional index))
  50. (declare-function eldoc-get-var-docstring "eldoc" (sym))
  51. (declare-function eldoc-fnsym-in-current-sexp "eldoc"))
  52. ;;; Evaluation Result
  53. ;;
  54. ;;
  55. ;; Internal
  56. (defvar helm-eldoc-active-minibuffers-list nil)
  57. (defvar helm-eval-expression-map
  58. (let ((map (make-sparse-keymap)))
  59. (set-keymap-parent map helm-map)
  60. (define-key map (kbd "<C-return>") 'helm-eval-new-line-and-indent)
  61. (define-key map (kbd "<M-tab>") 'lisp-indent-line)
  62. (define-key map (kbd "<C-tab>") 'helm-lisp-completion-at-point)
  63. (define-key map (kbd "C-p") 'previous-line)
  64. (define-key map (kbd "C-n") 'next-line)
  65. (define-key map (kbd "<up>") 'previous-line)
  66. (define-key map (kbd "<down>") 'next-line)
  67. (define-key map (kbd "<right>") 'forward-char)
  68. (define-key map (kbd "<left>") 'backward-char)
  69. map))
  70. (defun helm-build-evaluation-result-source ()
  71. (helm-build-dummy-source "Evaluation Result"
  72. :multiline t
  73. :mode-line "C-RET: nl-and-indent, M-tab: reindent, C-tab:complete, C-p/n: next/prec-line."
  74. :filtered-candidate-transformer (lambda (_candidates _source)
  75. (list
  76. (condition-case nil
  77. (with-helm-current-buffer
  78. (pp-to-string
  79. (if edebug-active
  80. (edebug-eval-expression
  81. (read helm-pattern))
  82. (eval (read helm-pattern)))))
  83. (error "Error"))))
  84. :nohighlight t
  85. :keymap helm-eval-expression-map
  86. :action '(("Copy result to kill-ring" . (lambda (candidate)
  87. (kill-new
  88. (replace-regexp-in-string
  89. "\n" "" candidate))
  90. (message "Result copied to kill-ring")))
  91. ("copy sexp to kill-ring" . (lambda (_candidate)
  92. (kill-new helm-input)
  93. (message "Sexp copied to kill-ring"))))))
  94. (defun helm-eval-new-line-and-indent ()
  95. (interactive)
  96. (newline) (lisp-indent-line))
  97. (defun helm-eldoc-store-minibuffer ()
  98. "Store minibuffer buffer name in `helm-eldoc-active-minibuffers-list'."
  99. (with-selected-window (minibuffer-window)
  100. (push (current-buffer) helm-eldoc-active-minibuffers-list)))
  101. (defun helm-eldoc-show-in-eval ()
  102. "Return eldoc in mode-line for current minibuffer input."
  103. (let ((buf (window-buffer (active-minibuffer-window))))
  104. (condition-case err
  105. (when (member buf helm-eldoc-active-minibuffers-list)
  106. (with-current-buffer buf
  107. (let* ((sym (save-excursion
  108. (unless (looking-back ")\\|\"" (1- (point)))
  109. (forward-char -1))
  110. (eldoc-current-symbol)))
  111. (info-fn (eldoc-fnsym-in-current-sexp))
  112. (doc (or (eldoc-get-var-docstring sym)
  113. (eldoc-get-fnsym-args-string
  114. (car info-fn) (cadr info-fn)))))
  115. (when doc (funcall helm-eldoc-in-minibuffer-show-fn doc)))))
  116. (error (message "Eldoc in minibuffer error: %S" err) nil))))
  117. (defun helm-show-info-in-mode-line (str)
  118. "Display string STR in mode-line."
  119. (save-selected-window
  120. (with-current-buffer helm-buffer
  121. (let ((mode-line-format (concat " " str)))
  122. (force-mode-line-update)
  123. (sit-for helm-show-info-in-mode-line-delay))
  124. (force-mode-line-update))))
  125. ;;; Calculation Result
  126. ;;
  127. ;;
  128. (defvar helm-source-calculation-result
  129. (helm-build-dummy-source "Calculation Result"
  130. :filtered-candidate-transformer (lambda (_candidates _source)
  131. (list
  132. (condition-case nil
  133. (calc-eval helm-pattern)
  134. (error "error"))))
  135. :nohighlight t
  136. :action '(("Copy result to kill-ring" . (lambda (candidate)
  137. (kill-new candidate)
  138. (message "Result \"%s\" copied to kill-ring"
  139. candidate)))
  140. ("Copy operation to kill-ring" . (lambda (_candidate)
  141. (kill-new helm-input)
  142. (message "Calculation copied to kill-ring"))))))
  143. ;;;###autoload
  144. (defun helm-eval-expression (arg)
  145. "Preconfigured helm for `helm-source-evaluation-result'."
  146. (interactive "P")
  147. (helm :sources (helm-build-evaluation-result-source)
  148. :input (when arg (thing-at-point 'sexp))
  149. :buffer "*helm eval*"
  150. :echo-input-in-header-line nil
  151. :history 'read-expression-history))
  152. (defvar eldoc-idle-delay)
  153. ;;;###autoload
  154. (defun helm-eval-expression-with-eldoc ()
  155. "Preconfigured helm for `helm-source-evaluation-result' with `eldoc' support."
  156. (interactive)
  157. (let ((timer (run-with-idle-timer
  158. eldoc-idle-delay 'repeat
  159. 'helm-eldoc-show-in-eval)))
  160. (unwind-protect
  161. (minibuffer-with-setup-hook
  162. 'helm-eldoc-store-minibuffer
  163. (call-interactively 'helm-eval-expression))
  164. (and timer (cancel-timer timer))
  165. (setq helm-eldoc-active-minibuffers-list
  166. (cdr helm-eldoc-active-minibuffers-list)))))
  167. ;;;###autoload
  168. (defun helm-calcul-expression ()
  169. "Preconfigured helm for `helm-source-calculation-result'."
  170. (interactive)
  171. (helm :sources 'helm-source-calculation-result
  172. :buffer "*helm calcul*"))
  173. (provide 'helm-eval)
  174. ;; Local Variables:
  175. ;; byte-compile-warnings: (not obsolete)
  176. ;; coding: utf-8
  177. ;; indent-tabs-mode: nil
  178. ;; End:
  179. ;;; helm-eval.el ends here