Merge branch 'console'

Refactor and improve console integration.  It is decoupled from
notebook module now.  As a result, ein:console-open works in
other buffers such as connected buffer now.
This commit is contained in:
Takafumi Arakaki 2012-08-16 16:43:21 +02:00
commit ef9739dea3
9 changed files with 223 additions and 169 deletions

View file

@ -93,7 +93,7 @@ Requirements
* (optional) python-mode:
It should work with either python.el or python-mode.el.
Fabian Gallina's `python.el`_ is required to use
``ein:notebook-console-open`` command.
``ein:console-open`` command.
* (optional) `auto-complete.el`_
You need to configure subpackage ``ein-ac`` to enable
this feature.
@ -185,7 +185,7 @@ Keybinds - Notebook
C-c C-l ein:notebook-clear-output-command
C-c RET ein:notebook-merge-cell-command
C-c C-n ein:notebook-goto-next-input-command
C-c C-o ein:notebook-console-open
C-c C-o ein:console-open
C-c C-p ein:notebook-goto-prev-input-command
C-c C-q ein:notebook-kill-kernel-then-close-command
C-c C-r ein:notebook-restart-kernel-command

View file

@ -5,7 +5,9 @@
(add-to-list 'load-path "~/.emacs.d/el-get/popup/") ; for auto-complete
(require 'ein-notebooklist)
(require 'ein-console)
(require 'ein-shared-output)
(require 'ein-traceback)
(require 'ein-mumamo)
(require 'ein-ac)
(require 'ein-connect)

View file

@ -51,7 +51,7 @@ Links:
* `Issue Tracker at GitHub
<https://github.com/tkf/emacs-ipython-notebook/issues>`_
.. [#] You need to setup :el:symbol:`ein:notebook-console-args` properly
.. [#] You need to setup :el:symbol:`ein:console-args` properly
.. [#] Use the command :el:symbol:`ein:connect-to-notebook-command`.
.. contents::
@ -84,7 +84,7 @@ Requirements
* (optional) python-mode:
It should work with either python.el or `python-mode.el`_ [#]_.
Fabian Gallina's `python.el`_ is required to use
:el:symbol:`ein:notebook-console-open` command.
:el:symbol:`ein:console-open` command.
* (optional) `auto-complete.el`_
You need to configure :el:symbol:`ein:use-auto-complete` to enable
this feature.
@ -310,15 +310,19 @@ Notebook
.. el:variable:: ein:notebook-kill-buffer-ask
.. el:variable:: ein:notebook-querty-timeout-open
.. el:variable:: ein:notebook-querty-timeout-save
.. el:variable:: ein:notebook-console-security-dir
.. el:variable:: ein:notebook-console-executable
.. el:variable:: ein:notebook-console-args
.. el:variable:: ein:cell-traceback-level
.. el:variable:: ein:cell-autoexec-prompt
.. el:variable:: ein:scratch-notebook-name-template
.. el:variable:: ein:iexec-delay
.. el:variable:: ein:complete-on-dot
Console
^^^^^^^
.. el:variable:: ein:console-security-dir
.. el:variable:: ein:console-executable
.. el:variable:: ein:console-args
Connect
^^^^^^^
@ -479,6 +483,9 @@ Change Log
v0.1.2
------
* Rename command :el:symbol:`ein:notebook-console-open` to
:el:symbol:`ein:console-open`. It is available from non-notebook
buffer such as connected buffer now.
* Add :el:symbol:`ein:connect-reload-buffer`.
Old default :el:symbol:`ein:connect-run-buffer` behavior is
replaced by this function. :el:symbol:`ein:connect-run-buffer`

View file

@ -65,7 +65,7 @@ of OPTION:
(defcustom ein:connect-run-command "%run"
"``%run`` magic command used for `ein:connect-run-buffer'.
Types same as `ein:notebook-console-security-dir' are valid."
Types same as `ein:console-security-dir' are valid."
:type '(choice
(string :tag "command" "%run")
(alist :tag "command mapping"
@ -347,6 +347,7 @@ change the cells to run."
(define-key map "\C-c\C-i" 'ein:connect-complete-command)
(define-key map "\C-c\C-z" 'ein:connect-pop-to-notebook)
(define-key map "\C-c\C-a" 'ein:connect-toggle-autoexec)
(define-key map "\C-c\C-o" 'ein:console-open)
(define-key map "\C-c\C-x" 'ein:tb-show)
(define-key map "\M-." 'ein:pytools-jump-to-source-command)
(define-key map (kbd "C-c C-.") 'ein:pytools-jump-to-source-command)

177
lisp/ein-console.el Normal file
View file

@ -0,0 +1,177 @@
;;; ein-console.el --- IPython console integration
;; Copyright (C) 2012 Takafumi Arakaki
;; Author: Takafumi Arakaki <aka.tkf at gmail.com>
;; This file is NOT part of GNU Emacs.
;; ein-console.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-console.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-console.el. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;
;;; Code:
(require 'ein)
(require 'ein-utils)
;; Functions from `Fabian Gallina's python.el`_
;; NOTE: Do *not* load python.el here, since user may be using the other
;; version of python-mode.
(declare-function python-shell-make-comint "python")
(declare-function python-shell-get-process-name "python")
(declare-function python-shell-switch-to-shell "python")
;;; Define aliases to old variables and functions.
(define-obsolete-variable-alias
'ein:notebook-console-security-dir 'ein:console-security-dir "0.1.2")
(define-obsolete-variable-alias
'ein:notebook-console-executable 'ein:console-executable "0.1.2")
(define-obsolete-variable-alias
'ein:notebook-console-args 'ein:console-args "0.1.2")
(define-obsolete-function-alias
'ein:notebook-console-open 'ein:console-open "0.1.2")
;;; Configuration
(defcustom ein:console-security-dir ""
"Security directory setting.
Following types are valid:
string
Use this value as a path to security directory.
Handy when you have only one IPython server.
alist
An alist whose element is \"(URL-OR-PORT . DIR)\".
Key (URL-OR-PORT) can be string (URL), integer (port), or
`default' (symbol). The value of `default' is used when
other key does not much. Normally you should have this
entry.
function
Called with an argument URL-OR-PORT (integer or string).
You can have complex setting using this."
:type '(choice
(string :tag "Security directory"
"~/.config/ipython/profile_nbserver/security/")
(alist :tag "Security directory 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 "Security directory"))
(function :tag "Security directory getter"
(lambda (url-or-port)
(format "~/.config/ipython/profile_%s/security/"
url-or-port))))
:group 'ein)
(defcustom ein:console-executable (executable-find "ipython")
"IPython executable used for console.
Example: ``\"/user/bin/ipython\"``.
Types same as `ein:console-security-dir' are valid."
:type '(choice
(string :tag "IPython executable" "/user/bin/ipython")
(alist :tag "IPython executable 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 "IPython executable"
"/user/bin/ipython"))
(function :tag "IPython executable getter"
(lambda (url-or-port) (executable-find "ipython"))))
:group 'ein)
(defcustom ein:console-args "--profile nbserver"
"Additional argument when using console.
Example: ``\"--ssh HOSTNAME\"``.
Types same as `ein:console-security-dir' are valid."
:type '(choice
(string :tag "Arguments to IPython"
"--profile nbserver --ssh HOSTNAME")
(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"))
(function :tag "Additional arguments getter"
(lambda (url-or-port)
(format "--ssh %s" url-or-port))))
:group 'ein)
(defun ein:console-security-dir-get (url-or-port)
(let ((dir (ein:choose-setting 'ein:console-security-dir url-or-port)))
(if (equal dir "")
dir
(file-name-as-directory (expand-file-name dir)))))
(defun ein:console-executable-get (url-or-port)
(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))
(defun ein:console-make-command ()
(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)))
(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;
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'.
(interactive)
(if (fboundp 'python-shell-switch-to-shell)
(let ((cmd (ein:console-make-command))
;; python.el settings:
(python-shell-setup-codes nil)
;; python.el makes dedicated process when
;; `buffer-file-name' has some value.
(buffer-file-name (buffer-name)))
;; The following line does what `run-python' does.
;; But as `run-python' changed the call signature in the new
;; version, let's do this manually.
;; See also: https://github.com/tkf/emacs-ipython-notebook/pull/50
(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!")))
(provide 'ein-console)
;;; ein-console.el ends here

View file

@ -1347,7 +1347,7 @@ Do not use `python-mode'. Use plain mode when MuMaMo is not installed::
(define-key map "\C-c\C-z" 'ein:notebook-kernel-interrupt-command)
(define-key map "\C-c\C-q" 'ein:notebook-kill-kernel-then-close-command)
(define-key map (kbd "C-:") 'ein:shared-output-eval-string)
(define-key map "\C-c\C-o" 'ein:notebook-console-open)
(define-key map "\C-c\C-o" 'ein:console-open)
(define-key map "\C-x\C-s" 'ein:notebook-save-notebook-command)
(define-key map "\C-x\C-w" 'ein:notebook-rename-command)
(define-key map "\M-." 'ein:pytools-jump-to-source-command)
@ -1477,134 +1477,6 @@ Called via `kill-emacs-query-functions'."
(ein:log 'info "Canceled to kill all notebooks."))
(ein:log 'info "No opened notebooks."))))
;;; Console integration
(defcustom ein:notebook-console-security-dir ""
"Security directory setting.
Following types are valid:
string
Use this value as a path to security directory.
Handy when you have only one IPython server.
alist
An alist whose element is \"(URL-OR-PORT . DIR)\".
Key (URL-OR-PORT) can be string (URL), integer (port), or
`default' (symbol). The value of `default' is used when
other key does not much. Normally you should have this
entry.
function
Called with an argument URL-OR-PORT (integer or string).
You can have complex setting using this."
:type '(choice
(string :tag "Security directory"
"~/.config/ipython/profile_nbserver/security/")
(alist :tag "Security directory 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 "Security directory"))
(function :tag "Security directory getter"
(lambda (url-or-port)
(format "~/.config/ipython/profile_%s/security/"
url-or-port))))
:group 'ein)
(defcustom ein:notebook-console-executable (executable-find "ipython")
"IPython executable used for console.
Example: ``\"/user/bin/ipython\"``.
Types same as `ein:notebook-console-security-dir' are valid."
:type '(choice
(string :tag "IPython executable" "/user/bin/ipython")
(alist :tag "IPython executable 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 "IPython executable"
"/user/bin/ipython"))
(function :tag "IPython executable getter"
(lambda (url-or-port) (executable-find "ipython"))))
:group 'ein)
(defcustom ein:notebook-console-args "--profile nbserver"
"Additional argument when using console.
Example: ``\"--ssh HOSTNAME\"``.
Types same as `ein:notebook-console-security-dir' are valid."
:type '(choice
(string :tag "Arguments to IPython"
"--profile nbserver --ssh HOSTNAME")
(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"))
(function :tag "Additional arguments getter"
(lambda (url-or-port)
(format "--ssh %s" url-or-port))))
:group 'ein)
(defun ein:notebook-console-security-dir-get (notebook)
(let ((dir (ein:choose-setting 'ein:notebook-console-security-dir
(ein:$notebook-url-or-port notebook))))
(if (equal dir "")
dir
(file-name-as-directory (expand-file-name dir)))))
(defun ein:notebook-console-executable-get (notebook)
(ein:choose-setting 'ein:notebook-console-executable
(ein:$notebook-url-or-port notebook)))
(defun ein:notebook-console-args-get (notebook)
(ein:choose-setting 'ein:notebook-console-args
(ein:$notebook-url-or-port notebook)))
;; `Fabian Gallina's python.el`_
(declare-function python-shell-make-comint "python")
(declare-function python-shell-get-process-name "python")
(declare-function python-shell-switch-to-shell "python")
(defun ein:notebook-console-open ()
"Open IPython console.
To use this function, `ein:notebook-console-security-dir' and
`ein:notebook-console-args' must be set properly.
This function requires `Fabian Gallina's python.el`_ for now;
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:notebook-console-security-dir'.
(interactive)
(unless ein:notebook (error "Not in notebook buffer!"))
(if (fboundp 'python-shell-switch-to-shell)
(let* ((dir (ein:notebook-console-security-dir-get ein:notebook))
(kid (ein:$kernel-kernel-id
(ein:$notebook-kernel ein:notebook)))
(ipy (ein:notebook-console-executable-get ein:notebook))
(args (ein:notebook-console-args-get ein:notebook))
;; python.el settings:
(python-shell-setup-codes nil)
(cmd
(format "python %s console --existing %skernel-%s.json %s"
ipy dir kid args))
;; python.el makes dedicated process when
;; `buffer-file-name' has some value.
(buffer-file-name (buffer-name)))
;; The following line does what `run-python' does.
;; But as `run-python' changed the call signature in the new
;; version, let's do this manually.
;; See also: https://github.com/tkf/emacs-ipython-notebook/pull/50
(python-shell-make-comint cmd (python-shell-get-process-name t))
;; Pop to inferior Python process buffer
(python-shell-switch-to-shell))
(ein:log 'warn "python.el is not loaded!")))
(provide 'ein-notebook)
;;; ein-notebook.el ends here

View file

@ -46,6 +46,8 @@
(autoload 'ein:notebook-name "ein-notebook")
(autoload 'ein:kernel-id "ein-kernel")
(autoload 'ein:console-open "ein-console" nil t)
(autoload 'ein:connect-to-notebook-command "ein-connect" nil t)
(autoload 'ein:connect-to-notebook "ein-connect" nil t)
(autoload 'ein:connect-to-notebook-buffer "ein-connect" nil t)

25
tests/test-ein-console.el Normal file
View file

@ -0,0 +1,25 @@
(require 'ein-console)
(ert-deftest ein:console-security-dir-string ()
(let ((ein:console-security-dir "/some/dir/"))
(should (equal (ein:console-security-dir-get "DUMMY-URL-OR-PORT")
ein:console-security-dir))))
(ert-deftest ein:console-security-dir-list ()
(let ((ein:console-security-dir
'((8888 . "/dir/8888/")
("htttp://dummy.org" . "/dir/http/")
(7777 . my-secret-directory)
(default . "/dir/default/")))
(my-secret-directory "/dir/secret/"))
(should (equal (ein:console-security-dir-get 8888) "/dir/8888/"))
(should (equal (ein:console-security-dir-get "htttp://dummy.org")
"/dir/http/"))
(should (equal (ein:console-security-dir-get 7777) "/dir/secret/"))
(should (equal (ein:console-security-dir-get 9999) "/dir/default/"))))
(ert-deftest ein:console-security-dir-func ()
(let ((ein:console-security-dir
'(lambda (x) (should (equal x "DUMMY-URL-OR-PORT")) "/dir/")))
(should (equal (ein:console-security-dir-get "DUMMY-URL-OR-PORT")
"/dir/"))))

View file

@ -702,38 +702,6 @@ value of `ein:notebook-enable-undo'."
(should-not (ein:notebook-test-notebook-name "a\\b"))
(should (ein:notebook-test-notebook-name "This is a OK notebook name")))
(ert-deftest ein:notebook-console-security-dir-string ()
(let ((ein:notebook-console-security-dir "/some/dir/")
(notebook (ein:notebook-new "DUMMY-URL-OR-PORT" "DUMMY-NOTEBOOK-ID")))
(should (equal (ein:notebook-console-security-dir-get notebook)
ein:notebook-console-security-dir))))
(ert-deftest ein:notebook-console-security-dir-list ()
(let ((ein:notebook-console-security-dir
'((8888 . "/dir/8888/")
("htttp://dummy.org" . "/dir/http/")
(7777 . my-secret-directory)
(default . "/dir/default/")))
(my-secret-directory "/dir/secret/"))
(let ((notebook (ein:notebook-new 8888 "DUMMY-NOTEBOOK-ID")))
(should (equal (ein:notebook-console-security-dir-get notebook)
"/dir/8888/")))
(let ((notebook (ein:notebook-new "htttp://dummy.org" "DUMMY-NOTEBOOK-ID")))
(should (equal (ein:notebook-console-security-dir-get notebook)
"/dir/http/")))
(let ((notebook (ein:notebook-new 7777 "DUMMY-NOTEBOOK-ID")))
(should (equal (ein:notebook-console-security-dir-get notebook)
"/dir/secret/")))
(let ((notebook (ein:notebook-new 9999 "DUMMY-NOTEBOOK-ID")))
(should (equal (ein:notebook-console-security-dir-get notebook)
"/dir/default/")))))
(ert-deftest ein:notebook-console-security-dir-func ()
(let ((ein:notebook-console-security-dir
'(lambda (x) (should (equal x "DUMMY-URL-OR-PORT")) "/dir/"))
(notebook (ein:notebook-new "DUMMY-URL-OR-PORT" "DUMMY-NOTEBOOK-ID")))
(should (equal (ein:notebook-console-security-dir-get notebook) "/dir/"))))
(defun* eintest:notebook--check-nbformat (&optional orig_nbformat
orig_nbformat_minor
nbformat