Merge branch 'console-open-wo-python-el'

As mentioned in #91, the error message "python.el is not loaded!"
was not good for Emacs 23 users.  Rather than explaining about
three python modes, just open dumb comint buffer.

Since make-comint-in-buffer takes a list of string, spec for
ein:console-args is changed to "list of argument" from "space
separated argument".  Old configuration works but warning will
appear.
This commit is contained in:
Takafumi Arakaki 2012-12-06 23:54:37 +01:00
commit f43524048f
5 changed files with 121 additions and 26 deletions

View file

@ -543,6 +543,7 @@ Change Log
v0.2
----
* :el:symbol:`ein:console-open` works without `python.el`_.
* Expand code cell output on execution.
(`#88 <https://github.com/tkf/emacs-ipython-notebook/issues/88>`_).
* Improve :el:symbol:`ein:completer-dot-complete` and

View file

@ -101,24 +101,47 @@ Types same as `ein:console-security-dir' are valid."
(lambda (url-or-port) (executable-find "ipython"))))
:group 'ein)
(defcustom ein:console-args "--profile nbserver"
(defcustom ein:console-args '("--profile" "nbserver")
"Additional argument when using console.
Example: ``\"--ssh HOSTNAME\"``.
Types same as `ein:console-security-dir' are valid."
.. warning:: Space-separated string is obsolete now. Use a list
of string as value now.
Setting to use IPython profile named \"YOUR-IPYTHON-PROFILE\"::
(setq ein:console-args '(\"--profile\" \"YOUR-IPYTHON-PROFILE\"))
Together with `ein:console-security-dir', you can open IPython
console connecting to a remote kernel.::
(setq ein:console-args '(\"--ssh\" \"HOSTNAME\"))
(setq ein:console-security-dir \"PATH/TO/SECURITY/DIR\")
You can setup `ein:console-args' per server basis using alist form::
(setq ein:console-args
'((8888 . '(\"--profile\" \"PROFILE\"))
(8889 . '(\"--ssh\" \"HOSTNAME\"))
(default . '(\"--profile\" \"default\"))))
If you want to use more complex setting, you can set a function to it::
(setq ein:console-args
(lambda (url-or-port) '(\"--ssh\" \"HOSTNAME\")))
See also: `ein:console-security-dir'."
:type '(choice
(string :tag "Arguments to IPython"
"--profile nbserver --ssh HOSTNAME")
(repeat (string :tag "Arguments to IPython" "--profile"))
(alist :tag "Arguments mapping"
:key-type (choice :tag "URL or PORT"
(string :tag "URL" "http://127.0.0.1:8888")
(integer :tag "PORT" 8888)
(const default))
:value-type (string :tag "Arguments to IPython"
"--profile nbserver --ssh HOSTNAME"))
:value-type
(repeat (string :tag "Arguments to IPython" "--profile")))
(function :tag "Additional arguments getter"
(lambda (url-or-port)
(format "--ssh %s" url-or-port))))
(list "--ssh" (format "%s" url-or-port)))))
:group 'ein)
(defun ein:console-security-dir-get (url-or-port)
@ -131,32 +154,52 @@ Types same as `ein:console-security-dir' are valid."
(ein:choose-setting 'ein:console-executable url-or-port))
(defun ein:console-args-get (url-or-port)
(ein:choose-setting 'ein:console-args url-or-port))
(ein:choose-setting 'ein:console-args url-or-port
(lambda (x)
(or (stringp x)
(and (listp x)
(stringp (car x)))))))
(defun ein:console-make-command ()
;; FIXME: use %connect_info to get connection file, then I can get
;; rid of `ein:console-security-dir'.
(let* ((url-or-port (or (ein:get-url-or-port)
(error "Cannot find notebook to connect!")))
(dir (ein:console-security-dir-get url-or-port))
(kid (ein:kernel-id (ein:get-kernel)))
(ipy (ein:console-executable-get url-or-port))
(args (ein:console-args-get url-or-port)))
(format "python %s console --existing %skernel-%s.json %s"
ipy dir kid args)))
;; FIMXE: do I need "python" here?
(append (list "python" ipy "console" "--existing"
(format "%skernel-%s.json" dir kid))
(if (listp args)
args
(ein:display-warning-once
"String value for `ein:console-args' is obsolete.
Use list of string instead of space separated string.")
(split-string-and-unquote args)))))
(defun ein:console-get-buffer ()
(let ((url-or-port (ein:get-url-or-port))
(notebook (ein:get-notebook)))
(format "*ein:console %s/%s*" url-or-port (ein:notebook-name notebook))))
;;;###autoload
(defun ein:console-open ()
"Open IPython console.
To use this function, `ein:console-security-dir' and
`ein:console-args' must be set properly.
This function requires `Fabian Gallina's python.el`_ for now;
This function works best with the new python.el_ which is shipped
with Emacs 24.2 or later. If you don't have it, this function
opens a \"plain\" command line interpreter (comint) buffer where
you cannot use fancy stuff such as TAB completion.
It should be possible to support python-mode.el. Patches are welcome!
.. _`Fabian Gallina's python.el`: https://github.com/fgallina/python.el"
;; FIXME: use %connect_info to get connection file, then I can get
;; rid of `ein:console-security-dir'.
.. _python.el: https://github.com/fgallina/python.el"
(interactive)
(if (fboundp 'python-shell-switch-to-shell)
(let ((cmd (ein:console-make-command))
(let ((cmd (mapconcat #'shell-quote-argument
(ein:console-make-command) " "))
;; python.el settings:
(python-shell-setup-codes nil)
;; python.el makes dedicated process when
@ -169,9 +212,14 @@ It should be possible to support python-mode.el. Patches are welcome!
(python-shell-make-comint cmd (python-shell-get-process-name t))
;; Pop to inferior Python process buffer
(python-shell-switch-to-shell))
(error "python.el is not loaded!")))
(let* ((command (ein:console-make-command))
(program (car command))
(args (cdr command))
(buffer (ein:console-get-buffer)))
(apply #'make-comint-in-buffer
"ein:console" buffer program nil args)
(pop-to-buffer buffer))))
(provide 'ein-console)
;;; ein-console.el ends here

View file

@ -424,12 +424,15 @@ Elements are compared using the function TEST (default: `eq')."
((boundp obj) (eval obj))
((fboundp obj) (funcall obj))))
(defun ein:choose-setting (symbol value)
(defun ein:choose-setting (symbol value &optional single-p)
"Choose setting in stored in SYMBOL based on VALUE.
The value of SYMBOL can be string, alist or function."
The value of SYMBOL can be string, alist or function.
SINGLE-P is a function which takes one argument. It must
return t when the value of SYMBOL can be used as a setting.
SINGLE-P is `stringp' by default."
(let ((setting (eval symbol)))
(cond
((stringp setting) setting)
((funcall (or single-p 'stringp) setting) setting)
((functionp setting) (funcall setting value))
((listp setting)
(ein:get-value (or (assoc-default value setting)
@ -506,6 +509,16 @@ Use `ein:log' for debugging and logging."
;; FIXME: Call `ein:log' here (but do not display in minibuffer).
(display-warning 'ein message level))
(defvar ein:display-warning-once--db
(make-hash-table :test 'equal))
(defun ein:display-warning-once (message &optional level)
"Call `ein:display-warning' once for same MESSAGE and LEVEL."
(let ((key (list message level)))
(unless (gethash key ein:display-warning-once--db)
(ein:display-warning message level)
(puthash key t ein:display-warning-once--db))))
(defun ein:get-docstring (function)
"Return docstring of FUNCTION."
;; Borrowed from `ac-symbol-documentation'.

View file

@ -109,10 +109,12 @@
;;; Finally, open notebook list
(require 'ein-dev)
(ein:dev-print-sys-info)
(unless noninteractive
(call-interactively #'ein:notebooklist-open))
(if noninteractive
(progn
;; When called in batch mode, print system info.
(require 'ein-dev)
(ein:dev-print-sys-info))
;; To make EIN configurable by --eval, use idle timer:
(run-with-idle-timer 0 nil 'call-interactively 'ein:notebooklist-open))
;;; zeroein.el ends here

View file

@ -149,3 +149,34 @@ def f():
(should (equal (ein:list-move-right '(a b c d) 'c) '(a b d c)))
(should (equal (ein:list-move-right '(a b c d) 'd) '(d a b c)))
(should-error (ein:list-move-right '(a b c d) 'X)))
(defun ein:testing-choose-setting-should-equal
(setting value desired &optional single-p)
(let ((setting setting))
(should (equal (ein:choose-setting 'setting value single-p) desired))))
(ert-deftest ein:choose-setting-single-string ()
(let ((test 'ein:testing-choose-setting-should-equal))
(funcall test "a" nil "a")
(funcall test "a" 'whatever "a")))
(ert-deftest ein:choose-setting-single-int ()
(let ((test #'ein:testing-choose-setting-should-equal))
(funcall test 1 nil 1 #'integerp)
(funcall test 1 'whatever 1 #'integerp)))
(ert-deftest ein:choose-setting-alist ()
(let* ((test (lambda (&rest args)
(apply #'ein:testing-choose-setting-should-equal
'(("a" . 1) ("b" . 2) ("c" . 3))
args))))
(funcall test "a" 1)
(funcall test "b" 2)))
(ert-deftest ein:choose-setting-func ()
(let* ((test (lambda (&rest args)
(apply #'ein:testing-choose-setting-should-equal
(lambda (x) 1)
args))))
(funcall test nil 1)
(funcall test 'whatever 1)))