mirror of https://github.com/Chizi123/.emacs.d.git

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