123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348 |
- ;;; ein-dev.el --- Development tools
- ;; Copyright (C) 2012- Takafumi Arakaki
- ;; Author: Takafumi Arakaki <aka.tkf at gmail.com>
- ;; This file is NOT part of GNU Emacs.
- ;; ein-dev.el is free software: you can redistribute it and/or modify
- ;; it under the terms of the GNU General Public License as published by
- ;; the Free Software Foundation, either version 3 of the License, or
- ;; (at your option) any later version.
- ;; ein-dev.el is distributed in the hope that it will be useful,
- ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ;; GNU General Public License for more details.
- ;; You should have received a copy of the GNU General Public License
- ;; along with ein-dev.el. If not, see <http://www.gnu.org/licenses/>.
- ;;; Commentary:
- ;;
- ;;; Code:
- (eval-when-compile (require 'cl))
- (declare-function rst-shift-region "rst")
- (require 'ein-notebook)
- (require 'ein-subpackages)
- ;;;###autoload
- (defun ein:dev-insert-mode-map (map-string)
- "Insert mode-map into rst document. For README.rst."
- (save-excursion
- (insert "\n\n::\n\n")
- (let ((beg (point)))
- (search-forward ".. // KEYS END //")
- (move-beginning-of-line nil)
- (delete-region beg (point))
- (insert "\n")
- (goto-char beg)
- (insert (substitute-command-keys map-string))
- (rst-shift-region beg (point) 1))))
- (defun ein:load-files (&optional regex dir ignore-compiled)
- (let* ((dir (or dir ein:source-dir))
- (regex (or regex ".+"))
- (files (and
- (file-accessible-directory-p dir)
- (directory-files dir 'full regex))))
- (unless ignore-compiled
- (setq files (mapcar #'file-name-sans-extension files)))
- (mapc #'load files)))
- (defun ein:dev-reload ()
- "Reload ein-*.el modules."
- (interactive)
- (ein:notebook-kill-all-buffers)
- (makunbound 'ein:notebook-mode-map) ; so defvar works.
- (load "ein-notebook") ; ... but make sure it will be defined first.
- (ein:load-files "^ein-.*\\.el$")
- (ein:subpackages-reload))
- (defun* ein:dev-require-all (&key (ignore-p #'ignore))
- (loop for f in (directory-files ein:source-dir nil "^ein-.*\\.el$")
- unless (or (equal f "ein-pkg.el")
- (funcall ignore-p f))
- do (require (intern (file-name-sans-extension f)) nil t))
- ;; For `widget-button-press':
- (require 'wid-edit nil t))
- (defadvice backtrace (around ein:dev-short-backtrace)
- "A hack to shorten backtrace.
- As code cells hold base64-encoded image data, backtrace tends to
- be VERY long. So I am setting `print-level' to *1*. Note that
- setting it globally via `setq' does not work because the value
- for debugger is hard-coded. See `debugger-setup-buffer'."
- (let ((print-level 1))
- ad-do-it))
- (defun ein:dev-patch-backtrace ()
- "Monkey patch `backtrace' function to make it shorter."
- (interactive)
- (ad-enable-advice 'backtrace 'around 'ein:dev-short-backtrace)
- (ad-activate 'backtrace))
- (defun ein:dev-depatch-backtrace ()
- "Undo `ein:dev-patch-backtrace'."
- (interactive)
- (ad-deactivate 'backtrace)
- (ad-disable-advice 'backtrace 'around 'ein:dev-short-backtrace)
- ;; In case it has other advices.
- (ad-activate 'backtrace))
- (defun ein:dev-show-debug-setting ()
- "Show variables related to EIN debugging."
- (interactive)
- (message (concat "debug-on-error=%s websocket-debug=%s "
- "websocket-callback-debug-on-error=%s "
- "ein:debug=%s ein:log-level=%s ein:log-message-level=%s")
- debug-on-error websocket-debug websocket-callback-debug-on-error
- ein:debug
- (ein:log-level-int-to-name ein:log-level)
- (ein:log-level-int-to-name ein:log-message-level)))
- ;;;###autoload
- (defun ein:dev-start-debug (&optional ws-callback)
- "Enable EIN debugging support.
- When the prefix argument is given, debugging support for websocket
- callback (`websocket-callback-debug-on-error') is enabled."
- (interactive "P")
- (setq debug-on-error t)
- (setq websocket-debug t)
- (when ws-callback
- (setq websocket-callback-debug-on-error t))
- (setq ein:debug t)
- (ein:log-set-level 'debug)
- (ein:log-set-message-level 'verbose)
- (ein:dev-patch-backtrace)
- (ein:dev-show-debug-setting))
- ;;;###autoload
- (defun ein:dev-stop-debug ()
- "Disable debugging support enabled by `ein:dev-start-debug'."
- (interactive)
- (setq debug-on-error nil)
- (setq websocket-debug nil)
- (setq websocket-callback-debug-on-error nil)
- (setq ein:debug nil)
- (ein:log-set-level 'verbose)
- (ein:log-set-message-level 'info)
- (ein:dev-depatch-backtrace)
- (ein:dev-show-debug-setting))
- (defun ein:dev-pop-to-debug-shell ()
- "Open shell channel websocket log buffer."
- (interactive)
- (pop-to-buffer
- (websocket-get-debug-buffer-create
- (ein:$websocket-ws (ein:$kernel-shell-channel
- (ein:$notebook-kernel ein:%notebook%))))))
- (defun ein:dev-pop-to-debug-iopub ()
- "Open iopub channel websocket log buffer."
- (interactive)
- (pop-to-buffer
- (websocket-get-debug-buffer-create
- (ein:$websocket-ws (ein:$kernel-iopub-channel
- (ein:$notebook-kernel ein:%notebook%))))))
- (defun ein:dev-notebook-plain-mode ()
- "Use `ein:notebook-plain-mode'."
- (interactive)
- (setq ein:notebook-modes '(ein:notebook-plain-mode)))
- (defun ein:dev-notebook-python-mode ()
- "Use `ein:notebook-python-mode'."
- (interactive)
- (setq ein:notebook-modes '(ein:notebook-python-mode)))
- (defun ein:dev-notebook-mumamo-mode ()
- "Use `ein:notebook-mumamo-mode'."
- (interactive)
- (setq ein:notebook-modes '(ein:notebook-mumamo-mode)))
- (defun ein:dev-notebook-multilang-mode ()
- "Use `ein:notebook-multilang-mode'."
- (interactive)
- (setq ein:notebook-modes '(ein:notebook-multilang-mode)))
- (defun ein:dev-sys-info--lib (name)
- (let* ((libsym (intern-soft name))
- (version-var (loop for fmt in '("%s-version" "%s:version")
- if (intern-soft (format fmt name))
- return it))
- (version (symbol-value version-var)))
- (list :name name
- :path (ein:aand (locate-library name) (abbreviate-file-name it))
- :featurep (featurep libsym)
- :version-var version-var
- :version version)))
- (defun ein:dev-dump-vars (names)
- (loop for var in names
- collect (intern (format ":%s" var))
- collect (symbol-value (intern (format "ein:%s" var)))))
- (defun ein:dev-stdout-program (command args)
- "Safely call COMMAND with ARGS and return its stdout."
- (ein:aand (executable-find command)
- (with-temp-buffer
- (erase-buffer)
- (apply #'call-process it nil t nil args)
- (buffer-string))))
- (defun ein:dev-sys-info ()
- (list
- "EIN system info"
- :emacs-version (emacs-version)
- :emacs-bzr-version (ein:eval-if-bound 'emacs-bzr-version)
- :window-system window-system
- ;; Emacs variant detection
- ;; http://coderepos.org/share/browser/lang/elisp/init-loader/init-loader.el
- :emacs-variant
- (cond ((featurep 'meadow) 'meadow)
- ((featurep 'carbon-emacs-package) 'carbon))
- :os (list
- :uname (ein:dev-stdout-program "uname" '("-a"))
- :lsb-release (ein:dev-stdout-program "lsb_release" '("-a")))
- :image-types (ein:eval-if-bound 'image-types)
- :image-types-available (ein:filter #'image-type-available-p
- (ein:eval-if-bound 'image-types))
- :request (list :backend request-backend)
- :ein (append (list :version (ein:version))
- (ein:dev-dump-vars '("source-dir")))
- :lib (ein:filter (lambda (info) (plist-get info :path))
- (mapcar #'ein:dev-sys-info--lib
- '("websocket" "request" "auto-complete" "mumamo"
- "auto-complete" "popup" "fuzzy" "pos-tip"
- "python" "python-mode" "markdown-mode"
- "smartrep" "anything" "helm")))))
- (defun ein:dev-show-sys-info (&optional show-in-buffer)
- "Show Emacs and library information."
- (interactive (list t))
- (let ((info (ein:dev-sys-info)))
- (if show-in-buffer
- (let ((buffer (get-buffer-create "*ein:sys-info*")))
- (with-current-buffer buffer
- (erase-buffer)
- (pp info buffer)
- (pop-to-buffer buffer)))
- (message "EIN INFO:\n%s" (pp-to-string info)))))
- ;;;###autoload
- (defun ein:dev-bug-report-template ()
- "Open a buffer with bug report template."
- (interactive)
- (let ((buffer (generate-new-buffer "*ein:bug-report*")))
- (with-current-buffer buffer
- (erase-buffer)
- (insert "<!--
- This template is to help you write a good bug report.
- You may skip some sections, but please make sure to include
- the last section \"System info\", unless you find some
- personal information there.
- After finish writing it, please post it here:
- https://github.com/tkf/emacs-ipython-notebook/issues/new
- -->
- ## Check list
- - [ ] I read \"Avoid standard Emacs traps\" section in
- https://github.com/tkf/emacs-ipython-notebook/blob/master/CONTRIBUTING.md
- - [ ] I checked that IPython works with the browser interface.
- - [ ] I checked that the problem was not due to badly compiled
- files. Removing `*.elc` files from source directory of EIN and
- its dependencies did not solve the problem.
- - [ ] I checked that the libraries are loaded from intended place.
- (You can check the location in the \"System info\" section below)
- ## Description of the problem you have
- ## Steps to reproduce the problem
- 1.
- 2.
- 3.
- ## Expected output
- ## Your EIN configuration (in .emacs.d/init.el or somewhere else)
- ## Your IPython configuration
- 1. What is your IPython version? (run `ipython --version`):
- 2. How do you start IPython? (e.g., `ipython notebook --port 9999`):
- 3. What is your IPython notebook port number or URL?:
- ## Additional information (if any)
- ")
- (insert "## System info:\n\n```cl\n")
- (condition-case err
- (ein:dev-print-sys-info buffer)
- (error (insert (format "`ein:dev-sys-info' produce: %S" err))))
- (insert "```\n")
- (goto-char (point-min))
- (when (fboundp 'markdown-mode)
- (markdown-mode))
- (pop-to-buffer buffer))))
- (defun ein:dev-print-sys-info (&optional stream)
- (princ (ein:dev--pp-to-string (ein:dev-sys-info))
- (or stream standard-output)))
- (defun ein:dev--pp-to-string (object)
- "`pp-to-string' with additional prettifier."
- (with-temp-buffer
- (erase-buffer)
- (let ((pp-escape-newlines nil))
- (pp object (current-buffer)))
- (goto-char (point-min))
- (let ((emacs-lisp-mode-hook nil))
- (emacs-lisp-mode))
- (ein:dev--prettify-sexp)
- (buffer-string)))
- (defun ein:dev--prettify-sexp ()
- "Prettify s-exp at point recursively.
- Use this function in addition to `pp' (see `ein:dev--pp-to-string')."
- (down-list)
- (condition-case nil
- (while t
- (forward-sexp)
- ;; Prettify nested s-exp.
- (when (looking-back ")")
- (save-excursion
- (backward-sexp)
- (ein:dev--prettify-sexp)))
- ;; Add newline before keyword symbol.
- (when (looking-at-p " :")
- (newline-and-indent))
- ;; Add newline before long string literal.
- (when (and (looking-at-p " \"")
- (let ((end (save-excursion
- (forward-sexp)
- (point))))
- (> (- end (point)) 80)))
- (newline-and-indent)))
- (scan-error)))
- (provide 'ein-dev)
- ;;; ein-dev.el ends here
|