]> crepu.dev Git - config.git/blob - djavu-asus/emacs/elpa/elpy-20230803.1455/elpy-profile.el
8a2195ee6b33cec908c4f8c1f5ce8d638ba585e3
[config.git] / djavu-asus / emacs / elpa / elpy-20230803.1455 / elpy-profile.el
1 ;;; elpy-profile.el --- Profiling capabilitiss for elpy
2
3 ;; Copyright (C) 2013-2019 Jorgen Schaefer
4
5 ;; Author: Gaby Launay <gaby.launay@tutanota.com>
6 ;; URL: https://github.com/jorgenschaefer/elpy
7
8 ;; This program is free software; you can redistribute it and/or
9 ;; modify it under the terms of the GNU General Public License
10 ;; as published by the Free Software Foundation; either version 3
11 ;; of the License, or (at your option) any later version.
12
13 ;; This program is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
20
21 ;;; Commentary:
22
23 ;; This file serves as an extension to elpy by adding profiling capabilities
24
25 ;;; Code:
26
27
28 ;;;;;;;;;;;;;;;;;;;;;;
29 ;;; User customization
30
31 (defcustom elpy-profile-visualizer "snakeviz"
32 "Visualizer for elpy profile results."
33 :type '(choice (const :tag "Snakeviz" "snakeviz")
34 (const :tag "RunSnakeRun" "runsnake")
35 (const :tag "pyprof2calltree" "pyprof2calltree -k -i")
36 (string :tag "Other"))
37 :group 'elpy)
38
39 ;;;;;;;;;;;;;;;;;;;;;;
40 ;;; Helper Functions
41
42 (defun elpy-profile--display-profiling (file)
43 "Display the profile result FILE using `elpy-profile-visualizer'."
44 (let ((exec (car (split-string elpy-profile-visualizer " " t)))
45 (args (append (cdr (split-string elpy-profile-visualizer " " t)) (list file))))
46 (if (executable-find exec)
47 (apply 'call-process exec nil 0 nil args)
48 (message "Elpy profile visualizer '%s' not found" exec))))
49
50 (defun elpy-profile--sentinel (process string)
51 "Elpy profile sentinel."
52 (let ((filename (file-name-nondirectory (process-get process 'file)))
53 (prof-file (process-get process 'prof-file))
54 (dont-display (process-get process 'dont-display)))
55 (with-current-buffer "*elpy-profile-log*"
56 (view-mode))
57 (if (not (string-equal string "finished\n"))
58 (progn
59 (message "[%s] Profiling failed" filename)
60 (display-buffer "*elpy-profile-log*"))
61 (message "[%s] Profiling succeeded" filename)
62 (unless dont-display
63 (elpy-profile--display-profiling prof-file)))))
64
65 (defun elpy-profile--file (file &optional in-dir dont-display)
66 "Profile asynchronously FILE and display the result using
67 `elpy-profile-visualizer'.
68
69 If IN-DIR is non nil, profile result is saved in the same
70 directory as the script.
71 If DONT-DISPLAY is non nil, don't display the profile results."
72 (ignore-errors (kill-buffer "*elpy-profile-log*"))
73 (let* ((prof-file (if in-dir
74 (concat (file-name-sans-extension file) ".profile")
75 (concat (make-temp-file "elpy-profile-" nil ".profile"))))
76 (proc-name (format "elpy-profile-%s" file))
77 (proc-cmd (list elpy-rpc-python-command "-m" "cProfile" "-o" prof-file file))
78 (proc (make-process :name proc-name
79 :buffer "*elpy-profile-log*"
80 :sentinel 'elpy-profile--sentinel
81 :command proc-cmd)))
82 (message "[%s] Profiling ..." (file-name-nondirectory file))
83 (process-put proc 'prof-file prof-file)
84 (process-put proc 'file file)
85 (process-put proc 'dont-display dont-display)
86 prof-file))
87
88 ;;;;;;;;;;;;;;;;;;;;;;
89 ;;; User Functions
90
91 (defun elpy-profile-buffer-or-region (&optional in-dir dont-display)
92 "Profile asynchronously the active region or the current buffer
93 and display the result using `elpy-profile-visualizer'.
94
95 If IN-DIR is non nil, profile result is saved in the same
96 directory as the script.
97 If DONT-DISPLAY is non nil, don't display the profile results."
98 (interactive "P")
99 (let* ((file-name (buffer-name))
100 (file-dir (file-name-directory (buffer-file-name)))
101 (beg (if (region-active-p) (region-beginning) (point-min)))
102 (end (if (region-active-p) (region-end) (point-max)))
103 (tmp-file-prefix (if (region-active-p) "_region_" ""))
104 (tmp-file (if in-dir
105 (concat file-dir "/" tmp-file-prefix file-name)
106 (concat (make-temp-file "elpy-profile-" t) "/" tmp-file-prefix file-name)))
107 (region (python-shell-buffer-substring beg end)))
108 (with-temp-buffer
109 (insert region)
110 (write-region (point-min) (point-max) tmp-file nil t))
111 (elpy-profile--file tmp-file t dont-display)))
112
113 (provide 'elpy-profile)
114 ;;; elpy-profile.el ends here