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.

111 lines
4.4 KiB

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