ein-console.el 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. ;;; ein-console.el --- IPython console integration
  2. ;; Copyright (C) 2012 Takafumi Arakaki
  3. ;; Author: Takafumi Arakaki <aka.tkf at gmail.com>
  4. ;; This file is NOT part of GNU Emacs.
  5. ;; ein-console.el 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. ;; ein-console.el 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 ein-console.el. If not, see <http://www.gnu.org/licenses/>.
  15. ;;; Commentary:
  16. ;;
  17. ;;; Code:
  18. (require 'ein-core)
  19. ;; Functions from `Fabian Gallina's python.el`_
  20. ;; NOTE: Do *not* load python.el here, since user may be using the other
  21. ;; version of python-mode.
  22. (declare-function python-shell-make-comint "python")
  23. (declare-function python-shell-get-process-name "python")
  24. (declare-function python-shell-switch-to-shell "python")
  25. ;;; Define aliases to old variables and functions.
  26. (define-obsolete-variable-alias
  27. 'ein:notebook-console-security-dir 'ein:console-security-dir "0.1.2")
  28. (define-obsolete-variable-alias
  29. 'ein:notebook-console-executable 'ein:console-executable "0.1.2")
  30. (define-obsolete-variable-alias
  31. 'ein:notebook-console-args 'ein:console-args "0.1.2")
  32. (define-obsolete-function-alias
  33. 'ein:notebook-console-open 'ein:console-open "0.1.2")
  34. ;;; Configuration
  35. (defcustom ein:console-security-dir ""
  36. "Security directory setting.
  37. Following types are valid:
  38. string
  39. Use this value as a path to security directory.
  40. Handy when you have only one IPython server.
  41. alist
  42. An alist whose element is \"(URL-OR-PORT . DIR)\".
  43. Key (URL-OR-PORT) can be string (URL), integer (port), or
  44. `default' (symbol). The value of `default' is used when
  45. other key does not much. Normally you should have this
  46. entry.
  47. function
  48. Called with an argument URL-OR-PORT (integer or string).
  49. You can have complex setting using this."
  50. :type '(choice
  51. (string :tag "Security directory"
  52. "~/.config/ipython/profile_nbserver/security/")
  53. (alist :tag "Security directory mapping"
  54. :key-type (choice :tag "URL or PORT"
  55. (string :tag "URL" "http://127.0.0.1:8888")
  56. (integer :tag "PORT" 8888)
  57. (const default))
  58. :value-type (string :tag "Security directory"))
  59. (function :tag "Security directory getter"
  60. (lambda (url-or-port)
  61. (format "~/.config/ipython/profile_%s/security/"
  62. url-or-port))))
  63. :group 'ein)
  64. (defcustom ein:console-executable (executable-find "ipython")
  65. "IPython executable used for console.
  66. Example: ``\"/user/bin/ipython\"``.
  67. Types same as `ein:console-security-dir' are valid."
  68. :type '(choice
  69. (string :tag "IPython executable" "/user/bin/ipython")
  70. (alist :tag "IPython executable mapping"
  71. :key-type (choice :tag "URL or PORT"
  72. (string :tag "URL" "http://127.0.0.1:8888")
  73. (integer :tag "PORT" 8888)
  74. (const default))
  75. :value-type (string :tag "IPython executable"
  76. "/user/bin/ipython"))
  77. (function :tag "IPython executable getter"
  78. (lambda (url-or-port) (executable-find "ipython"))))
  79. :group 'ein)
  80. (defcustom ein:console-args '("--profile" "nbserver")
  81. "Additional argument when using console.
  82. .. warning:: Space-separated string is obsolete now. Use a list
  83. of string as value now.
  84. Setting to use IPython profile named \"YOUR-IPYTHON-PROFILE\"::
  85. (setq ein:console-args '(\"--profile\" \"YOUR-IPYTHON-PROFILE\"))
  86. Together with `ein:console-security-dir', you can open IPython
  87. console connecting to a remote kernel.::
  88. (setq ein:console-args '(\"--ssh\" \"HOSTNAME\"))
  89. (setq ein:console-security-dir \"PATH/TO/SECURITY/DIR\")
  90. You can setup `ein:console-args' per server basis using alist form::
  91. (setq ein:console-args
  92. '((8888 . '(\"--profile\" \"PROFILE\"))
  93. (8889 . '(\"--ssh\" \"HOSTNAME\"))
  94. (default . '(\"--profile\" \"default\"))))
  95. If you want to use more complex setting, you can set a function to it::
  96. (setq ein:console-args
  97. (lambda (url-or-port) '(\"--ssh\" \"HOSTNAME\")))
  98. See also: `ein:console-security-dir'."
  99. :type '(choice
  100. (repeat (string :tag "Arguments to IPython" "--profile"))
  101. (alist :tag "Arguments mapping"
  102. :key-type (choice :tag "URL or PORT"
  103. (string :tag "URL" "http://127.0.0.1:8888")
  104. (integer :tag "PORT" 8888)
  105. (const default))
  106. :value-type
  107. (repeat (string :tag "Arguments to IPython" "--profile")))
  108. (function :tag "Additional arguments getter"
  109. (lambda (url-or-port)
  110. (list "--ssh" (format "%s" url-or-port)))))
  111. :group 'ein)
  112. (defun ein:console-security-dir-get (url-or-port)
  113. (let ((dir (ein:choose-setting 'ein:console-security-dir url-or-port)))
  114. (if (equal dir "")
  115. dir
  116. (file-name-as-directory (expand-file-name dir)))))
  117. (defun ein:console-executable-get (url-or-port)
  118. (ein:choose-setting 'ein:console-executable url-or-port))
  119. (defun ein:console-args-get (url-or-port)
  120. (ein:choose-setting 'ein:console-args url-or-port
  121. (lambda (x)
  122. (or (stringp x)
  123. (and (listp x)
  124. (stringp (car x)))))))
  125. (defun ein:console-make-command ()
  126. ;; FIXME: use %connect_info to get connection file, then I can get
  127. ;; rid of `ein:console-security-dir'.
  128. (let* ((url-or-port (or (ein:get-url-or-port)
  129. (error "Cannot find notebook to connect!")))
  130. (dir (ein:console-security-dir-get url-or-port))
  131. (kid (ein:kernel-id (ein:get-kernel)))
  132. (ipy (ein:console-executable-get url-or-port))
  133. (args (ein:console-args-get url-or-port)))
  134. ;; FIMXE: do I need "python" here?
  135. (append (list "python" ipy "console" "--existing"
  136. (format "%skernel-%s.json" dir kid))
  137. (if (listp args)
  138. args
  139. (ein:display-warning-once
  140. "String value for `ein:console-args' is obsolete.
  141. Use list of string instead of space separated string.")
  142. (split-string-and-unquote args)))))
  143. (defun ein:console-get-buffer ()
  144. (let ((url-or-port (ein:get-url-or-port))
  145. (notebook (ein:get-notebook)))
  146. (format "*ein:console %s/%s*" url-or-port (ein:notebook-name notebook))))
  147. ;;;###autoload
  148. (defun ein:console-open ()
  149. "Open IPython console.
  150. To use this function, `ein:console-security-dir' and
  151. `ein:console-args' must be set properly.
  152. This function works best with the new python.el_ which is shipped
  153. with Emacs 24.2 or later. If you don't have it, this function
  154. opens a \"plain\" command line interpreter (comint) buffer where
  155. you cannot use fancy stuff such as TAB completion.
  156. It should be possible to support python-mode.el. Patches are welcome!
  157. .. _python.el: https://github.com/fgallina/python.el"
  158. (interactive)
  159. (if (fboundp 'python-shell-switch-to-shell)
  160. (let ((cmd (mapconcat #'shell-quote-argument
  161. (ein:console-make-command) " "))
  162. ;; python.el settings:
  163. (python-shell-setup-codes nil)
  164. ;; python.el makes dedicated process when
  165. ;; `buffer-file-name' has some value.
  166. (buffer-file-name (buffer-name)))
  167. ;; The following line does what `run-python' does.
  168. ;; But as `run-python' changed the call signature in the new
  169. ;; version, let's do this manually.
  170. ;; See also: https://github.com/tkf/emacs-ipython-notebook/pull/50
  171. (python-shell-make-comint cmd (python-shell-get-process-name t))
  172. ;; Pop to inferior Python process buffer
  173. (python-shell-switch-to-shell))
  174. (let* ((command (ein:console-make-command))
  175. (program (car command))
  176. (args (cdr command))
  177. (buffer (ein:console-get-buffer)))
  178. (apply #'make-comint-in-buffer
  179. "ein:console" buffer program nil args)
  180. (pop-to-buffer buffer))))
  181. (provide 'ein-console)
  182. ;;; ein-console.el ends here