mirror of
https://github.com/vale981/emacs-ipython-notebook
synced 2025-03-05 17:11:41 -05:00
commit
6b752bc36e
42 changed files with 763 additions and 639 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -27,6 +27,6 @@ _static
|
|||
.travis.yml.swp
|
||||
*.zip
|
||||
.gitattributes
|
||||
.ecukes-temp*
|
||||
.ecukes*
|
||||
dist
|
||||
*.ob-ein.ipynb
|
|
@ -20,8 +20,8 @@ In your `init.el` or `.emacs`, add the following:
|
|||
Now whatever changes you make to the repo will be reflected in new emacs instances.
|
||||
|
||||
Dev tools
|
||||
---------------
|
||||
Most dev functionality lies in `ein-dev.el` the most important of which is `ein:dev-start-debug` which activates full logging and backtrace on error.
|
||||
---------
|
||||
`M-x ein:dev-start-debug` activates full logging and backtrace on error.
|
||||
|
||||
Quick sanity checking
|
||||
---------------------
|
||||
|
|
2
Cask
2
Cask
|
@ -19,6 +19,8 @@
|
|||
(depends-on "auto-complete")
|
||||
(depends-on "company")
|
||||
(depends-on "smartrep")
|
||||
(depends-on "polymode")
|
||||
(depends-on "markdown-mode")
|
||||
(depends-on "px")
|
||||
(depends-on "f")
|
||||
(depends-on "s"))
|
||||
|
|
19
Makefile
19
Makefile
|
@ -19,14 +19,19 @@ README.rst: README.in.rst
|
|||
(load \"ein-notebook\") \
|
||||
(describe-minor-mode \"ein:notebook-mode\") \
|
||||
(with-current-buffer \"*Help*\" (princ (buffer-string))))" 2>/dev/null \
|
||||
| tools/readme-sed.sh "KEYS NOTEBOOK" README.in.rst > README.rst0
|
||||
| tools/readme-sed.sh "KEYS NOTEBOOK" README.in.rst "key.*binding" > README.rst0
|
||||
sed "/CI VERSION/c"`grep -o 'emacs-[0-9][.0-9]*' .travis.yml | sort -n | head -1 | grep -o '[.0-9]*'` README.rst0 > README.rst1
|
||||
grep ';;' lisp/ein.el \
|
||||
| awk '/;;;\s*Commentary/{within=1;next}/;;;\s*/{within=0}within' \
|
||||
| sed -e 's/^\s*;;*\s*//g' \
|
||||
| tools/readme-sed.sh "COMMENTARY" README.rst1 > README.rst0
|
||||
cask eval "(progn \
|
||||
(add-to-list 'load-path \"./lisp\") \
|
||||
(load \"ein-connect\") \
|
||||
(describe-minor-mode \"ein:connect-mode\") \
|
||||
(with-current-buffer \"*Help*\" (princ (buffer-string))))" 2>/dev/null \
|
||||
| tools/readme-sed.sh "KEYS CONNECT" README.rst0 > README.rst
|
||||
rm README.rst0
|
||||
| tools/readme-sed.sh "KEYS CONNECT" README.rst0 "key.*binding" > README.rst
|
||||
rm README.rst0 README.rst1
|
||||
|
||||
.PHONY: autoloads
|
||||
autoloads:
|
||||
|
@ -59,7 +64,13 @@ test-jupyterhub:
|
|||
-cask exec ecukes --tags @jupyterhub
|
||||
|
||||
.PHONY: test
|
||||
test: quick test-int
|
||||
test: quick test-int test-poly
|
||||
|
||||
.PHONY: test-poly
|
||||
test-poly:
|
||||
cask exec ert-runner -L ./lisp -L ./test -l test/testfunc.el test/test-poly.el test/test-func.el
|
||||
cp test/test-poly.el features/support/test-poly.el
|
||||
cask exec ecukes; (ret=$$? ; rm -f features/support/test-poly.el && exit $$ret)
|
||||
|
||||
.PHONY: test-int
|
||||
test-int:
|
||||
|
|
|
@ -4,9 +4,7 @@
|
|||
|
||||
--- or **E**\ IN **I**\ s not only for **N**\ otebooks.
|
||||
|
||||
Emacs IPython Notebook (EIN) lets you edit and run Jupyter_ (formerly IPython) notebooks within Emacs. It channels all the power of Emacs without the idiosyncrasies of in-browser editing.
|
||||
|
||||
EIN was originally written by tkf_. More `complete documentation`_ is available.
|
||||
.. COMMENTARY (see Makefile)
|
||||
|
||||
.. |build-status|
|
||||
image:: https://secure.travis-ci.org/millejoh/emacs-ipython-notebook.png?branch=master
|
||||
|
@ -29,21 +27,13 @@ Install from MELPA_ (recommended) or ``make install`` from github source.
|
|||
|
||||
Usage
|
||||
=====
|
||||
There are multiple, mutually exclusive ways to launch EIN.
|
||||
Start EIN using ONE of the following:
|
||||
|
||||
Launch a local session
|
||||
----------------------
|
||||
``M-x ein:jupyter-server-start`` (aliased ``M-x ein:run``) launches a jupyter process from emacs.
|
||||
- Open an ``.ipynb`` file normally in emacs and press ``C-c C-o``, or,
|
||||
- ``M-x ein:run`` launches a jupyter process from emacs, or,
|
||||
- ``M-x ein:login`` to a running jupyter server
|
||||
|
||||
Login to a local or remote session
|
||||
----------------------------------
|
||||
``M-x ein:notebooklist-login`` (aliased ``M-x ein:login``) to a running jupyter server.
|
||||
|
||||
Jupyter services relayed over HTTP such as ``mybinder.org`` require cookie authentication. Issuing ``C-u M-x ein:login`` prompts for cookie information. See the `Wiki`_ for more information.
|
||||
|
||||
Open a notebook file
|
||||
--------------------
|
||||
Open an ``.ipynb`` file normally in emacs and press ``C-c C-o``.
|
||||
Use ``C-u M-x ein:login`` for services such as ``mybinder.org`` requiring cookie authentication.
|
||||
|
||||
.. _Cask: https://cask.readthedocs.io/en/latest/guide/installation.html
|
||||
.. _MELPA: http://melpa.org/#/
|
||||
|
@ -51,40 +41,37 @@ Open an ``.ipynb`` file normally in emacs and press ``C-c C-o``.
|
|||
It doesn't work
|
||||
---------------
|
||||
|
||||
EIN is tested and developed on GNU Emacs and works best on Emacs versions 25.3
|
||||
and later. Your mileage may vary with the `spacemacs layer`_ and other
|
||||
*emacsen*. For a full list of dependencies see the `documentation`_.
|
||||
EIN is tested on GNU Emacs versions
|
||||
.. CI VERSION (see Makefile)
|
||||
and later. Your mileage may vary with the `spacemacs layer`_ and other *emacsen*.
|
||||
|
||||
You may also try to self-diagnose:
|
||||
|
||||
First invoke ``M-x ein:dev-start-debug``. Then reproduce the error.
|
||||
|
||||
Higher level diagnostics appear in ``M-x ein:log-pop-to-all-buffer``.
|
||||
High level diagnostics appear in ``M-x ein:log-pop-to-all-buffer``.
|
||||
|
||||
Lower level diagnostics (the actual ``curl`` requests) appear in ``M-x ein:log-pop-to-request-buffer``.
|
||||
Low level diagnostics appear in ``M-x ein:log-pop-to-request-buffer``.
|
||||
|
||||
If you cannot resolve the problem, file an issue using ``M-x ein:dev-bug-report-template``. Please ensure the resulting system output does not include information sensitive to your institution.
|
||||
|
||||
.. _`documentation`: http://millejoh.github.io/emacs-ipython-notebook/#requirements
|
||||
|
||||
Highlighted Features
|
||||
====================
|
||||
|
||||
* Easily copy cells between different notebooks.
|
||||
* Execute code from an arbitrary buffer in a running kernel. See `Keybindings - Connect`_.
|
||||
* Jump to definition via ``M-.``
|
||||
* Completion via company-mode_.
|
||||
* Limited jupyterhub_ support.
|
||||
If you cannot resolve the problem, file an issue using ``M-x ein:dev-bug-report-template``.
|
||||
|
||||
.. _spacemacs layer: https://github.com/syl20bnr/spacemacs/tree/master/layers/%2Blang/ipython-notebook
|
||||
.. _auto-complete: https://github.com/auto-complete/auto-complete
|
||||
.. _company-mode: https://github.com/company-mode/company-mode
|
||||
.. _jupyterhub: https://github.com/jupyterhub/jupyterhub
|
||||
|
||||
I want to use Elpy, ESS, LSP, etc.
|
||||
==================================
|
||||
|
||||
Enable `polymode`_ via::
|
||||
|
||||
M-x customize-group RET ein
|
||||
Toggle Ein:Polymode
|
||||
|
||||
Org-mode Integration
|
||||
====================
|
||||
|
||||
EIN provides org-babel functionality similar to ob-ipython_ and scimax_. Acknowledgements to those fine packages.
|
||||
EIN provides org-babel functionality similar to ob-ipython_ and scimax_.
|
||||
|
||||
*Language* is ``ein``. The ``:session`` header argument is the notebook url, e.g., ``https://localhost:8888/my.ipynb``, or simply ``localhost``, in which case EIN will evaluate org blocks in an anonymous notebook::
|
||||
|
||||
|
@ -98,40 +85,27 @@ EIN provides org-babel functionality similar to ob-ipython_ and scimax_. Acknow
|
|||
plt.plot(x,y)
|
||||
#+END_SRC
|
||||
|
||||
You may also specify the port, i.e., ``localhost:8889``. See `complete details`_.
|
||||
You may also specify the port, i.e., ``localhost:8889``. See `ob-ein details`_.
|
||||
|
||||
.. _ob-ipython: https://github.com/gregsexton/ob-ipython/
|
||||
.. _polymode: https://github.com/polymode/polymode
|
||||
.. _ob-ipython: https://github.com/gregsexton/ob-ipython
|
||||
.. _scimax: https://github.com/jkitchin/scimax
|
||||
.. _complete details: http://millejoh.github.io/emacs-ipython-notebook/#org-mode-integration
|
||||
.. _ob-ein details: http://millejoh.github.io/emacs-ipython-notebook/#org-mode-integration
|
||||
|
||||
Screenshots
|
||||
===========
|
||||
Connected Buffers
|
||||
=================
|
||||
|
||||
.. figure:: https://github.com/millejoh/emacs-ipython-notebook/wiki/images/demo_plotnormal.PNG
|
||||
:alt: Plotting in Emacs IPython Notebook
|
||||
Use ``M-x ein:connect-to-notebook`` to submit code from an arbitrary buffer to a running jupyter kernel. See `connected buffer details`_.
|
||||
|
||||
.. figure:: https://github.com/millejoh/emacs-ipython-notebook/wiki/images/R-kernel-example.PNG
|
||||
:alt: EIN connecting to an R kernel
|
||||
.. _connected buffer details: http://millejoh.github.io/emacs-ipython-notebook/#connected-buffer
|
||||
|
||||
See `more <https://github.com/millejoh/emacs-ipython-notebook/wiki/Screenshots>`_!
|
||||
|
||||
Keybindings - Notebook
|
||||
----------------------
|
||||
Keymap (C-h m)
|
||||
==============
|
||||
|
||||
::
|
||||
|
||||
.. KEYS NOTEBOOK (see Makefile)
|
||||
|
||||
Keybindings - Connect
|
||||
---------------------
|
||||
|
||||
You can execute code from an arbitrary buffer in a running kernel via
|
||||
``M-x ein:connect-to-notebook``.
|
||||
|
||||
::
|
||||
|
||||
.. KEYS CONNECT (see Makefile)
|
||||
|
||||
Links
|
||||
=====
|
||||
* `Complete documentation <http://millejoh.github.io/emacs-ipython-notebook/>`_
|
||||
|
|
109
README.rst
109
README.rst
|
@ -4,7 +4,9 @@
|
|||
|
||||
--- or **E**\ IN **I**\ s not only for **N**\ otebooks.
|
||||
|
||||
Emacs IPython Notebook (EIN) lets you edit and run Jupyter_ (formerly IPython) notebooks within Emacs. It channels all the power of Emacs without the idiosyncrasies of in-browser editing.
|
||||
Emacs IPython Notebook (EIN) lets you edit and run Jupyter_ (formerly IPython)
|
||||
notebooks within Emacs. It channels all the power of Emacs without the
|
||||
idiosyncrasies of in-browser editing.
|
||||
|
||||
EIN was originally written by tkf_. More `complete documentation`_ is available.
|
||||
|
||||
|
@ -29,21 +31,13 @@ Install from MELPA_ (recommended) or ``make install`` from github source.
|
|||
|
||||
Usage
|
||||
=====
|
||||
There are multiple, mutually exclusive ways to launch EIN.
|
||||
Start EIN using ONE of the following:
|
||||
|
||||
Launch a local session
|
||||
----------------------
|
||||
``M-x ein:jupyter-server-start`` (aliased ``M-x ein:run``) launches a jupyter process from emacs.
|
||||
- Open an ``.ipynb`` file normally in emacs and press ``C-c C-o``, or,
|
||||
- ``M-x ein:run`` launches a jupyter process from emacs, or,
|
||||
- ``M-x ein:login`` to a running jupyter server
|
||||
|
||||
Login to a local or remote session
|
||||
----------------------------------
|
||||
``M-x ein:notebooklist-login`` (aliased ``M-x ein:login``) to a running jupyter server.
|
||||
|
||||
Jupyter services relayed over HTTP such as ``mybinder.org`` require cookie authentication. Issuing ``C-u M-x ein:login`` prompts for cookie information. See the `Wiki`_ for more information.
|
||||
|
||||
Open a notebook file
|
||||
--------------------
|
||||
Open an ``.ipynb`` file normally in emacs and press ``C-c C-o``.
|
||||
Use ``C-u M-x ein:login`` for services such as ``mybinder.org`` requiring cookie authentication.
|
||||
|
||||
.. _Cask: https://cask.readthedocs.io/en/latest/guide/installation.html
|
||||
.. _MELPA: http://melpa.org/#/
|
||||
|
@ -51,40 +45,37 @@ Open an ``.ipynb`` file normally in emacs and press ``C-c C-o``.
|
|||
It doesn't work
|
||||
---------------
|
||||
|
||||
EIN is tested and developed on GNU Emacs and works best on Emacs versions 25.3
|
||||
and later. Your mileage may vary with the `spacemacs layer`_ and other
|
||||
*emacsen*. For a full list of dependencies see the `documentation`_.
|
||||
EIN is tested on GNU Emacs versions
|
||||
25.2
|
||||
and later. Your mileage may vary with the `spacemacs layer`_ and other *emacsen*.
|
||||
|
||||
You may also try to self-diagnose:
|
||||
|
||||
First invoke ``M-x ein:dev-start-debug``. Then reproduce the error.
|
||||
|
||||
Higher level diagnostics appear in ``M-x ein:log-pop-to-all-buffer``.
|
||||
High level diagnostics appear in ``M-x ein:log-pop-to-all-buffer``.
|
||||
|
||||
Lower level diagnostics (the actual ``curl`` requests) appear in ``M-x ein:log-pop-to-request-buffer``.
|
||||
Low level diagnostics appear in ``M-x ein:log-pop-to-request-buffer``.
|
||||
|
||||
If you cannot resolve the problem, file an issue using ``M-x ein:dev-bug-report-template``. Please ensure the resulting system output does not include information sensitive to your institution.
|
||||
|
||||
.. _`documentation`: http://millejoh.github.io/emacs-ipython-notebook/#requirements
|
||||
|
||||
Highlighted Features
|
||||
====================
|
||||
|
||||
* Easily copy cells between different notebooks.
|
||||
* Execute code from an arbitrary buffer in a running kernel. See `Keybindings - Connect`_.
|
||||
* Jump to definition via ``M-.``
|
||||
* Completion via company-mode_.
|
||||
* Limited jupyterhub_ support.
|
||||
If you cannot resolve the problem, file an issue using ``M-x ein:dev-bug-report-template``.
|
||||
|
||||
.. _spacemacs layer: https://github.com/syl20bnr/spacemacs/tree/master/layers/%2Blang/ipython-notebook
|
||||
.. _auto-complete: https://github.com/auto-complete/auto-complete
|
||||
.. _company-mode: https://github.com/company-mode/company-mode
|
||||
.. _jupyterhub: https://github.com/jupyterhub/jupyterhub
|
||||
|
||||
I want to use Elpy, ESS, LSP, etc.
|
||||
==================================
|
||||
|
||||
Enable `polymode`_ via::
|
||||
|
||||
M-x customize-group RET ein
|
||||
Toggle Ein:Polymode
|
||||
|
||||
Org-mode Integration
|
||||
====================
|
||||
|
||||
EIN provides org-babel functionality similar to ob-ipython_ and scimax_. Acknowledgements to those fine packages.
|
||||
EIN provides org-babel functionality similar to ob-ipython_ and scimax_.
|
||||
|
||||
*Language* is ``ein``. The ``:session`` header argument is the notebook url, e.g., ``https://localhost:8888/my.ipynb``, or simply ``localhost``, in which case EIN will evaluate org blocks in an anonymous notebook::
|
||||
|
||||
|
@ -98,25 +89,22 @@ EIN provides org-babel functionality similar to ob-ipython_ and scimax_. Acknow
|
|||
plt.plot(x,y)
|
||||
#+END_SRC
|
||||
|
||||
You may also specify the port, i.e., ``localhost:8889``. See `complete details`_.
|
||||
You may also specify the port, i.e., ``localhost:8889``. See `ob-ein details`_.
|
||||
|
||||
.. _ob-ipython: https://github.com/gregsexton/ob-ipython/
|
||||
.. _polymode: https://github.com/polymode/polymode
|
||||
.. _ob-ipython: https://github.com/gregsexton/ob-ipython
|
||||
.. _scimax: https://github.com/jkitchin/scimax
|
||||
.. _complete details: http://millejoh.github.io/emacs-ipython-notebook/#org-mode-integration
|
||||
.. _ob-ein details: http://millejoh.github.io/emacs-ipython-notebook/#org-mode-integration
|
||||
|
||||
Screenshots
|
||||
===========
|
||||
Connected Buffers
|
||||
=================
|
||||
|
||||
.. figure:: https://github.com/millejoh/emacs-ipython-notebook/wiki/images/demo_plotnormal.PNG
|
||||
:alt: Plotting in Emacs IPython Notebook
|
||||
Use ``M-x ein:connect-to-notebook`` to submit code from an arbitrary buffer to a running jupyter kernel. See `connected buffer details`_.
|
||||
|
||||
.. figure:: https://github.com/millejoh/emacs-ipython-notebook/wiki/images/R-kernel-example.PNG
|
||||
:alt: EIN connecting to an R kernel
|
||||
.. _connected buffer details: http://millejoh.github.io/emacs-ipython-notebook/#connected-buffer
|
||||
|
||||
See `more <https://github.com/millejoh/emacs-ipython-notebook/wiki/Screenshots>`_!
|
||||
|
||||
Keybindings - Notebook
|
||||
----------------------
|
||||
Keymap (C-h m)
|
||||
==============
|
||||
|
||||
::
|
||||
|
||||
|
@ -203,37 +191,6 @@ Keybindings - Notebook
|
|||
C-c M-{ ein:notebook-worksheet-move-prev
|
||||
C-c M-} ein:notebook-worksheet-move-next
|
||||
|
||||
Keybindings - Connect
|
||||
---------------------
|
||||
|
||||
You can execute code from an arbitrary buffer in a running kernel via
|
||||
``M-x ein:connect-to-notebook``.
|
||||
|
||||
::
|
||||
|
||||
key binding
|
||||
--- -------
|
||||
|
||||
C-c Prefix Command
|
||||
ESC Prefix Command
|
||||
C-: ein:shared-output-eval-string
|
||||
|
||||
M-, ein:pytools-jump-back-command
|
||||
M-. ein:pytools-jump-to-source-command
|
||||
|
||||
C-c C-a ein:connect-toggle-autoexec
|
||||
C-c C-c ein:connect-run-or-eval-buffer
|
||||
C-c C-h ein:pytools-request-tooltip-or-help
|
||||
C-c TAB ein:completer-complete
|
||||
C-c C-l ein:connect-reload-buffer
|
||||
C-c C-o ein:console-open
|
||||
C-c C-r ein:connect-eval-region
|
||||
C-c C-x ein:tb-show
|
||||
C-c C-z ein:connect-pop-to-notebook
|
||||
C-c C-, ein:pytools-jump-back-command
|
||||
C-c C-. ein:pytools-jump-to-source-command
|
||||
C-c C-/ ein:notebook-scratchsheet-open
|
||||
|
||||
Links
|
||||
=====
|
||||
* `Complete documentation <http://millejoh.github.io/emacs-ipython-notebook/>`_
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
@connect
|
||||
Scenario: Company completion in a python buffer
|
||||
Given I set "ein:completion-backend" to eval "(quote ein:use-company-backend)"
|
||||
Given I kill all websocket buffers
|
||||
|
@ -9,7 +10,6 @@ Scenario: Company completion in a python buffer
|
|||
And I type "import itertools"
|
||||
And I press "RET"
|
||||
And I call "ein:connect-run-buffer"
|
||||
And I wait 3 seconds
|
||||
And I type "itertools."
|
||||
And I call "company-complete"
|
||||
And I wait for completions "itertools.chain"
|
||||
|
@ -24,6 +24,7 @@ Scenario: Company completion in a python buffer
|
|||
Then I should see "itertools.chain"
|
||||
Then no completion traffic
|
||||
|
||||
@connect
|
||||
Scenario: Test shared eval
|
||||
Given new default notebook
|
||||
When I open temp file "connect.py"
|
||||
|
@ -31,9 +32,9 @@ Scenario: Test shared eval
|
|||
And I connect to default notebook
|
||||
And I evaluate the python code "1+1"
|
||||
And I switch to buffer like "*ein:shared-output*"
|
||||
And I dump buffer
|
||||
And I wait for buffer to say "2"
|
||||
|
||||
@connect
|
||||
Scenario: Connect buffer to a running notebook
|
||||
Given new default notebook
|
||||
When I open temp file "connect.py"
|
||||
|
@ -51,9 +52,10 @@ Scenario: Connect buffer to a running notebook
|
|||
And I press "RET"
|
||||
And I press "RET"
|
||||
And I call "ein:connect-eval-buffer"
|
||||
And I wait 2 seconds
|
||||
And I switch to log expr "ein:log-all-buffer-name"
|
||||
And I wait for buffer to say "test01"
|
||||
And I switch to buffer like "Untitled"
|
||||
And I evaluate the python code "test01()"
|
||||
And I switch to buffer like "*ein:shared-output*"
|
||||
And I dump buffer
|
||||
And I wait for buffer to say "'hello'"
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
@eldoc
|
||||
Scenario: not running server locally
|
||||
Given I enable "ein:enable-eldoc-support"
|
||||
Given I fset "ein:pytools-add-sys-path" to "ignore"
|
||||
Given I clear log expr "ein:log-all-buffer-name"
|
||||
Given new default notebook
|
||||
And I type "import math"
|
||||
And I press "C-a"
|
||||
|
@ -53,6 +53,13 @@ Scenario: company completion
|
|||
Given new default notebook
|
||||
Given I set "ein:completion-backend" to eval "(quote ein:use-none-backend)"
|
||||
|
||||
@rename
|
||||
Scenario: rename notebook
|
||||
Given new default notebook
|
||||
And I press "C-c C-/"
|
||||
And I switch to buffer like "Untitled"
|
||||
And rename notebook to "Renamed" succeeds
|
||||
|
||||
@switch
|
||||
Scenario: switch kernel
|
||||
Given new default notebook
|
||||
|
|
|
@ -45,6 +45,7 @@ Scenario: Specific port, portless localhost refers to same, concurrent execution
|
|||
|
||||
@org
|
||||
Scenario: portless url with path, image, C-c ' lets you C-c C-c as well
|
||||
Given I set "ein:completion-backend" to eval "(quote ein:use-none-backend)"
|
||||
Given I stop the server
|
||||
When I open temp file "path.org"
|
||||
And I call "org-mode"
|
||||
|
|
14
features/polymode.feature
Normal file
14
features/polymode.feature
Normal file
|
@ -0,0 +1,14 @@
|
|||
@poly
|
||||
Scenario: selection spans cells
|
||||
Given new default notebook
|
||||
And I press "C-c C-b"
|
||||
And I press "C-<up>"
|
||||
And I press "C-p"
|
||||
And I press "C-SPC"
|
||||
And I press "C-n"
|
||||
And I press "C-n"
|
||||
And I press "C-n"
|
||||
And I press "C-n"
|
||||
Then newlined region should be "In [ ]:\n\n\nIn [ ]:\n"
|
||||
And I press "C-g"
|
||||
Then the region should not be active
|
|
@ -30,12 +30,13 @@
|
|||
|
||||
(When "^I switch kernel to \"\\(.+\\)\"$"
|
||||
(lambda (kernel-name)
|
||||
(let ((notebook (ein:notebook-switch-kernel (ein:get-notebook) kernel-name)))
|
||||
(loop repeat 10
|
||||
until (ein:kernel-live-p (ein:$notebook-kernel notebook))
|
||||
do (sleep-for 0 500)
|
||||
finally do (should (string= "R" (ein:$kernelspec-language
|
||||
(ein:$notebook-kernelspec notebook))))))))
|
||||
(cl-letf (((symbol-function 'R-mode) #'ignore))
|
||||
(let ((notebook (ein:notebook-switch-kernel (ein:get-notebook) kernel-name)))
|
||||
(loop repeat 10
|
||||
until (ein:kernel-live-p (ein:$notebook-kernel notebook))
|
||||
do (sleep-for 0 500)
|
||||
finally do (should (string= "R" (ein:$kernelspec-language
|
||||
(ein:$notebook-kernelspec notebook)))))))))
|
||||
|
||||
(When "^I kill kernel$"
|
||||
(lambda ()
|
||||
|
@ -103,6 +104,21 @@
|
|||
(lambda (substr)
|
||||
(switch-to-buffer (car (-non-nil (mapcar (lambda (b) (if (search substr (buffer-name b)) b)) (buffer-list)))))))
|
||||
|
||||
(When "^rename notebook to \"\\(.+\\)\" succeeds$"
|
||||
(lambda (new-name)
|
||||
(let* ((old-name (ein:$notebook-notebook-name ein:%notebook%))
|
||||
(old-count
|
||||
(length (seq-filter (lambda (b)
|
||||
(search old-name (buffer-name b)))
|
||||
(buffer-list)))))
|
||||
(ein:notebook-rename-command new-name)
|
||||
(ein:testing-wait-until
|
||||
(lambda ()
|
||||
(= old-count
|
||||
(length (seq-filter (lambda (b)
|
||||
(search new-name (buffer-name b)))
|
||||
(buffer-list)))))))))
|
||||
|
||||
(When "^I am in notebooklist buffer$"
|
||||
(lambda ()
|
||||
(switch-to-buffer (ein:notebooklist-get-buffer (car (ein:jupyter-server-conn-info))))
|
||||
|
@ -160,6 +176,11 @@
|
|||
(ein:jupyter-server-start (executable-find "jupyterhub") nil))
|
||||
(ein:testing-wait-until (lambda () (ein:notebooklist-list)) nil 20000 1000))))
|
||||
|
||||
(When "^newlined region should be \"\\(.*\\)\"$"
|
||||
(lambda (region)
|
||||
(should (string= (s-replace "\\n" "\n" region)
|
||||
(buffer-substring-no-properties (region-beginning) (region-end))))))
|
||||
|
||||
(When "^I start \\(and login to \\)?the server configured \"\\(.*\\)\"$"
|
||||
(lambda (login config)
|
||||
(When "I stop the server")
|
||||
|
@ -301,17 +322,18 @@
|
|||
|
||||
(When "^I wait for cell to execute$"
|
||||
(lambda ()
|
||||
(let* ((cell (ein:worksheet-get-current-cell :cell-p #'ein:codecell-p))
|
||||
(orig (if (slot-boundp cell 'input-prompt-number)
|
||||
(slot-value cell 'input-prompt-number))))
|
||||
(call-interactively #'ein:worksheet-execute-cell)
|
||||
(ein:testing-wait-until
|
||||
(lambda ()
|
||||
(ein:aand (and (slot-boundp cell 'input-prompt-number)
|
||||
(slot-value cell 'input-prompt-number))
|
||||
(and (numberp it)
|
||||
(not (equal orig it)))))
|
||||
nil 10000 2000))))
|
||||
(poly-ein-base
|
||||
(let* ((cell (ein:worksheet-get-current-cell :cell-p #'ein:codecell-p))
|
||||
(orig (if (slot-boundp cell 'input-prompt-number)
|
||||
(slot-value cell 'input-prompt-number))))
|
||||
(call-interactively #'ein:worksheet-execute-cell)
|
||||
(ein:testing-wait-until
|
||||
(lambda ()
|
||||
(ein:aand (and (slot-boundp cell 'input-prompt-number)
|
||||
(slot-value cell 'input-prompt-number))
|
||||
(and (numberp it)
|
||||
(not (equal orig it)))))
|
||||
nil 10000 2000)))))
|
||||
|
||||
(When "^I undo again$"
|
||||
(lambda ()
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
do (sleep-for 0 500)
|
||||
finally do (when (ein:notebook-live-p notebook)
|
||||
(ein:display-warning (format "cannot close %s" path))))
|
||||
do (when (search "Untitled" path)
|
||||
do (when (or (search "Untitled" path) (search "Renamed" path))
|
||||
(ein:notebooklist-delete-notebook path)
|
||||
(loop repeat 8
|
||||
with fullpath = (concat (file-name-as-directory ein:testing-jupyter-server-root) path)
|
||||
|
@ -60,7 +60,6 @@
|
|||
|
||||
(Setup
|
||||
(ein:dev-start-debug)
|
||||
(setq ein:jupyter-server-args '("--no-browser" "--debug"))
|
||||
(setq ein:notebook-autosave-frequency 0)
|
||||
(setq ein:notebook-create-checkpoint-on-save nil)
|
||||
(setq ein:testing-dump-file-log (concat default-directory "log/ecukes.log"))
|
||||
|
@ -68,6 +67,7 @@
|
|||
(setq ein:testing-dump-file-server (concat default-directory "log/ecukes.server"))
|
||||
(setq ein:testing-dump-file-request (concat default-directory "log/ecukes.request"))
|
||||
(setq org-confirm-babel-evaluate nil)
|
||||
(setq transient-mark-mode t)
|
||||
(Given "I start and login to the server configured \"\\n\""))
|
||||
|
||||
(After
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
@undo
|
||||
Scenario: Undo turned off
|
||||
Given I disable "ein:worksheet-enable-undo"
|
||||
Given new default notebook
|
||||
|
@ -6,7 +7,7 @@ Scenario: Undo turned off
|
|||
And I undo demoting errors
|
||||
Then I should see message "demoted: (user-error No undo information in this buffer)"
|
||||
|
||||
@yank
|
||||
@undo
|
||||
Scenario: Kill yank doesn't break undo
|
||||
Given I enable "ein:worksheet-enable-undo"
|
||||
Given new default notebook
|
||||
|
@ -24,6 +25,7 @@ Scenario: Kill yank doesn't break undo
|
|||
And I press "C-/"
|
||||
Then the cursor should be at point "74"
|
||||
|
||||
@undo
|
||||
Scenario: Collapse doesn't break undo
|
||||
Given I enable "ein:worksheet-enable-undo"
|
||||
Given new default notebook
|
||||
|
@ -48,7 +50,7 @@ Scenario: Collapse doesn't break undo
|
|||
And I undo again
|
||||
Then the cursor should be at point "55"
|
||||
|
||||
@prob
|
||||
@undo
|
||||
Scenario: Test the conflagrative commands
|
||||
Given I enable "ein:worksheet-enable-undo"
|
||||
Given new default notebook
|
||||
|
@ -79,6 +81,7 @@ Scenario: Test the conflagrative commands
|
|||
And I undo again
|
||||
Then the cursor should be at point "22"
|
||||
|
||||
@undo
|
||||
Scenario: Clear output doesn't break undo
|
||||
Given I enable "ein:worksheet-enable-undo"
|
||||
Given new default notebook
|
||||
|
@ -103,6 +106,7 @@ Scenario: Clear output doesn't break undo
|
|||
And I undo again
|
||||
Then the cursor should be at point "55"
|
||||
|
||||
@undo
|
||||
Scenario: Moving cells doesn't break undo
|
||||
Given I enable "ein:worksheet-enable-undo"
|
||||
Given new default notebook
|
||||
|
@ -168,7 +172,7 @@ Scenario: Split and merge don't break undo
|
|||
And I undo again
|
||||
Then the cursor should be at point "50"
|
||||
|
||||
@reopened
|
||||
@undo
|
||||
Scenario: Undo needs to at least work for reopened notebooks
|
||||
Given I enable "ein:worksheet-enable-undo"
|
||||
Given old notebook "undo.ipynb"
|
||||
|
@ -215,7 +219,7 @@ Scenario: Undo needs to at least work for reopened notebooks
|
|||
And I undo again
|
||||
Then the cursor should be at point "125"
|
||||
|
||||
@toggle
|
||||
@undo
|
||||
Scenario: Toggling between markdown and codecell does not break undo
|
||||
Given I enable "ein:worksheet-enable-undo"
|
||||
Given new default notebook
|
||||
|
|
|
@ -97,7 +97,7 @@
|
|||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python",
|
||||
"name": "python"
|
||||
"name": "python3"
|
||||
},
|
||||
"name": "undo.ipynb"
|
||||
},
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
"Set to `t' to use preset a little bit hacky auto-complete configuration.
|
||||
When this option is enabled, cached omni completion is available."
|
||||
:type 'boolean
|
||||
:group 'ein-completion)
|
||||
:group 'ein)
|
||||
|
||||
(defvar ein:ac-sources (and (boundp 'ac-sources)
|
||||
(default-value 'ac-sources))
|
||||
|
@ -113,8 +113,7 @@ When this option is enabled, cached omni completion is available."
|
|||
(cons (lambda (_ content __)
|
||||
(ein:ac-prepare-completion (plist-get content :matches)))
|
||||
nil))
|
||||
#'ignore)))
|
||||
(ein:use-ac-jedi-backend (ein:jedi-complete))))
|
||||
#'ignore)))))
|
||||
|
||||
|
||||
;;; Completer interface
|
||||
|
@ -150,7 +149,6 @@ compatibility with `ein:completer-finish-completing-default'."
|
|||
(when matches ; No auto-complete drop-down list when no matches
|
||||
(let ((ac-expand-on-auto-complete expand))
|
||||
(ac-start))))
|
||||
;; Why `ac-start'? See: `jedi:complete'.
|
||||
|
||||
|
||||
;;; Async document request hack
|
||||
|
@ -235,7 +233,7 @@ first candidate when the `ac-menu' pops up."
|
|||
Adding `ac-sources' to them makes it impossible to different
|
||||
`ac-sources' between chunks, which is good for EIN but may not
|
||||
for other package."
|
||||
(and ein:%notebook%
|
||||
(and ein:notebook-mode
|
||||
(ein:eval-if-bound 'ein:notebook-mumamo-mode)
|
||||
(eql major-mode ein:mumamo-codecell-mode)
|
||||
(ein:ac-setup)))
|
||||
|
|
|
@ -216,7 +216,6 @@ a number will limit the number of lines in a cell output."
|
|||
(("markdown") 'ein:markdowncell)
|
||||
(("raw") 'ein:rawcell)
|
||||
(("heading") 'ein:headingcell)
|
||||
;; Defined in ein-shared-output.el:
|
||||
(("shared-output") 'ein:shared-output-cell)
|
||||
(t (error "No cell type called %S" type))))
|
||||
|
||||
|
@ -226,17 +225,6 @@ a number will limit the number of lines in a cell output."
|
|||
(setf (gethash 'slide_type ss-table) slide-type)
|
||||
ss-table))
|
||||
|
||||
(defun ein:preprocess-nb4-cell (cell-data)
|
||||
(let ((source (plist-get cell-data :source)))
|
||||
(when (and (string= (plist-get cell-data :cell_type) "markdown")
|
||||
(string-match "\\(^#+\\)" source)
|
||||
(not (string-match "\n+" source)))
|
||||
(let ((heading-level (match-end 0)))
|
||||
(plist-put cell-data :cell_type "heading")
|
||||
(plist-put cell-data :level heading-level)
|
||||
(plist-put cell-data :source (substring source (1+ heading-level))))))
|
||||
cell-data)
|
||||
|
||||
(defun ein:cell-from-type (type &rest args)
|
||||
(apply (ein:cell-class-from-type type) args))
|
||||
|
||||
|
@ -250,10 +238,9 @@ a number will limit the number of lines in a cell output."
|
|||
base-type)))
|
||||
|
||||
(defun ein:cell-from-json (data &rest args)
|
||||
(let ((data (ein:preprocess-nb4-cell data))
|
||||
(cell (ein:cell-init (apply #'ein:cell-from-type
|
||||
(ein:cell--determine-cell-type data) args)
|
||||
data)))
|
||||
(let ((cell (ein:cell-init (apply #'ein:cell-from-type
|
||||
(ein:cell--determine-cell-type data) args)
|
||||
data)))
|
||||
(when (plist-get data :metadata)
|
||||
(ein:oset-if-empty cell 'metadata (plist-get data :metadata))
|
||||
(ein:aif (plist-get (slot-value cell 'metadata) :slideshow)
|
||||
|
@ -328,9 +315,7 @@ a number will limit the number of lines in a cell output."
|
|||
do (progn
|
||||
(setf (slot-value new 'element)
|
||||
(plist-put (slot-value new 'element) k
|
||||
(plist-get old-element k)))
|
||||
)
|
||||
)
|
||||
(plist-get old-element k)))))
|
||||
;; setting ewoc nodes
|
||||
(loop for en in (ein:cell-all-element cell)
|
||||
for node = (ewoc-data en)
|
||||
|
@ -558,7 +543,7 @@ Return language name as a string or `nil' when not defined.
|
|||
(when (and (not (slot-value cell 'collapsed))
|
||||
(= index ein:cell-max-num-outputs)
|
||||
(> (point) (point-at-bol)))
|
||||
;; The first output which exceeds `ein:cell-max-num-outputs'.
|
||||
;; The first output which exceeds `ein:cell-max-num-outputs'.
|
||||
(ein:insert-read-only "\n"))
|
||||
(ein:insert-read-only "."))
|
||||
(let ((out (nth index (slot-value cell 'outputs))))
|
||||
|
@ -673,10 +658,12 @@ Return language name as a string or `nil' when not defined.
|
|||
"Set `:collapsed' slot of CELL and invalidate output ewoc nodes."
|
||||
(unless (eq (slot-value cell 'collapsed) collapsed)
|
||||
(setf (slot-value cell 'collapsed) collapsed)
|
||||
(apply #'ewoc-invalidate
|
||||
(slot-value cell 'ewoc)
|
||||
(append (ein:cell-element-get cell :output)
|
||||
(list (ein:cell-element-get cell :footer))))))
|
||||
(let ((inhibit-read-only t)
|
||||
(buffer-undo-list t))
|
||||
(apply #'ewoc-invalidate
|
||||
(slot-value cell 'ewoc)
|
||||
(append (ein:cell-element-get cell :output)
|
||||
(list (ein:cell-element-get cell :footer)))))))
|
||||
|
||||
(cl-defmethod ein:cell-collapse ((cell ein:codecell))
|
||||
(ein:cell-set-collapsed cell t))
|
||||
|
|
|
@ -27,18 +27,13 @@
|
|||
;;; Code:
|
||||
|
||||
(eval-when-compile (require 'cl))
|
||||
(require 'jedi-core nil t)
|
||||
(require 'deferred)
|
||||
(require 'ein-completer)
|
||||
(require 'company nil t)
|
||||
|
||||
(declare-function jedi:complete-request "jedi-core")
|
||||
|
||||
(autoload 'company-begin-backend "company")
|
||||
(autoload 'company-doc-buffer "company")
|
||||
|
||||
;; Duplicates ein:jedi--completer-complete in ein-jedi.
|
||||
;; Let's refactor and enhance our calm!
|
||||
(defun ein:company--deferred-complete ()
|
||||
(let ((d (deferred:new #'identity)))
|
||||
(ein:completer-complete
|
||||
|
@ -59,23 +54,6 @@
|
|||
(unless (stringp replies) ;; if not an error
|
||||
(ein:completions--prepare-matches prefix fetcher replies))))))
|
||||
|
||||
(defun ein:company--complete-jedi (fetcher)
|
||||
(deferred:$
|
||||
(deferred:parallel
|
||||
(jedi:complete-request)
|
||||
(ein:company--deferred-complete))
|
||||
(deferred:nextc it
|
||||
(lambda (replies)
|
||||
(ein:completions--prepare-matches-jedi fetcher replies)))))
|
||||
|
||||
(defun ein:completions--prepare-matches-jedi (cb replies)
|
||||
(destructuring-bind
|
||||
(_ ((&key matches &allow-other-keys) ; :complete_reply
|
||||
_metadata))
|
||||
replies
|
||||
(ein:completions--build-oinfo-cache matches)
|
||||
(funcall cb matches)))
|
||||
|
||||
(defun ein:completions--prepare-matches (prefix fetcher replies)
|
||||
(destructuring-bind
|
||||
((&key matches cursor_start cursor_end &allow-other-keys) ; :complete_reply
|
||||
|
@ -94,7 +72,8 @@
|
|||
(interactive (list 'interactive))
|
||||
(cl-case command
|
||||
(interactive (company-begin-backend 'ein:company-backend))
|
||||
(prefix (and (or (ein:worksheet-at-codecell-p) ein:connect-mode)
|
||||
(prefix (and (eq ein:completion-backend 'ein:use-company-backend)
|
||||
(or (ein:worksheet-at-codecell-p) ein:connect-mode)
|
||||
(ein:get-kernel)
|
||||
(ein:object-at-point)))
|
||||
(annotation (let ((kernel (ein:get-kernel)))
|
||||
|
@ -114,9 +93,6 @@
|
|||
(ein:aif cached it
|
||||
(unless (and (looking-at "[[:nonascii:]]") (ein:company--punctuation-check (thing-at-point 'line) (current-column)))
|
||||
(case ein:completion-backend
|
||||
(ein:use-company-jedi-backend
|
||||
(cons :async (lambda (cb)
|
||||
(ein:company--complete-jedi cb))))
|
||||
(t
|
||||
(cons :async
|
||||
(lambda (cb)
|
||||
|
|
|
@ -128,19 +128,13 @@
|
|||
(ein:case-equal msg-type
|
||||
(("stream" "display_data" "pyout" "execute_result")
|
||||
(ein:aif (plist-get content :text)
|
||||
(setf (gethash obj (ein:$kernel-oinfo-cache kernel)) (ein:json-read-from-string it))))
|
||||
(setf (gethash obj (ein:$kernel-oinfo-cache kernel))
|
||||
(ein:json-read-from-string it))))
|
||||
(("error" "pyerr")
|
||||
;; This should only happen if ein-pytools is not loaded, which can
|
||||
;; happen if the user restarts the kernel. Could probably use better logic
|
||||
;; to determine if pytools have been loaded or not.
|
||||
(ein:pytools-load-safely kernel)
|
||||
(ein:log 'verbose "ein:completions--prepare-oinfo: %S" (plist-get content :traceback)))))
|
||||
;; It's okay, bad things happen. Not everything in python is going to have a
|
||||
;; pdef, which might cause the call to the json parser to fail. No need to
|
||||
;; log an error as that will unnecessarily fill the log buffer, but we do
|
||||
;; register a debug message in case someone really needs to know what is
|
||||
;; happening.
|
||||
(error (ein:log 'debug "ein:completions--prepare-oinfo: [%s] %s" err obj)
|
||||
(ein:log 'verbose "ein:completions--prepare-oinfo: %s"
|
||||
(plist-get content :traceback)))))
|
||||
(error (ein:log 'verbose "ein:completions--prepare-oinfo: [%s] %s"
|
||||
(error-message-string err) output)
|
||||
(setf (gethash obj (ein:$kernel-oinfo-cache kernel)) :json-false))))
|
||||
|
||||
;;; Support for Eldoc
|
||||
|
|
|
@ -217,13 +217,16 @@ notebooks."
|
|||
"Evaluate the whole buffer. Note that this will run the code
|
||||
inside the ``if __name__ == \"__main__\":`` block."
|
||||
(interactive)
|
||||
(deferred:$
|
||||
(deferred:next
|
||||
(lambda ()
|
||||
(ein:shared-output-eval-string (ein:connect-get-kernel) (buffer-string) nil :silent t)))
|
||||
(deferred:nextc it
|
||||
(lambda ()
|
||||
(ein:connect-execute-autoexec-cells))))
|
||||
(lexical-let ((b (current-buffer)))
|
||||
(deferred:$
|
||||
(deferred:next
|
||||
(lambda ()
|
||||
(with-current-buffer b
|
||||
(ein:shared-output-eval-string (ein:connect-get-kernel) (buffer-string) nil :silent t))))
|
||||
(deferred:nextc it
|
||||
(lambda ()
|
||||
(with-current-buffer b
|
||||
(ein:connect-execute-autoexec-cells))))))
|
||||
(ein:log 'info "Whole buffer is sent to the kernel."))
|
||||
|
||||
(defun ein:connect-run-buffer (&optional ask-command)
|
||||
|
@ -399,13 +402,7 @@ notebook."
|
|||
(ein:use-ac-backend
|
||||
(define-key ein:connect-mode-map "." 'ein:ac-dot-complete)
|
||||
(auto-complete-mode))
|
||||
(ein:use-ac-jedi-backend
|
||||
(define-key ein:connect-mode-map "." 'ein:ac-dot-complete)
|
||||
(auto-complete-mode))
|
||||
(ein:use-company-backend
|
||||
(add-to-list 'company-backends #'ein:company-backend)
|
||||
(company-mode))
|
||||
(ein:use-company-jedi-backend
|
||||
(add-to-list 'company-backends #'ein:company-backend)
|
||||
(company-mode))))
|
||||
|
||||
|
|
|
@ -168,7 +168,6 @@ global setting. For global setting and more information, see
|
|||
:notebook-version (ein:$notebook-api-version nb)
|
||||
:raw-content nb-content)))
|
||||
|
||||
|
||||
;;; Managing/listing the content hierarchy
|
||||
|
||||
(defvar *ein:content-hierarchy* (make-hash-table :test #'equal)
|
||||
|
|
|
@ -42,10 +42,6 @@
|
|||
:group 'applications
|
||||
:prefix "ein:")
|
||||
|
||||
(defvar ein:version "0.15.0"
|
||||
"Version number for Emacs IPython Notebook (EIN).")
|
||||
|
||||
|
||||
;;; Configuration
|
||||
|
||||
(defcustom ein:url-or-port '(8888)
|
||||
|
@ -124,27 +120,25 @@ pair of TO-PYTHON and FROM-PYTHON."
|
|||
(defun ein:default-url-or-port ()
|
||||
(or ein:default-url-or-port (car ein:url-or-port) 8888))
|
||||
|
||||
(defun ein:version (&optional copy-to-kill)
|
||||
(defun ein:version (&optional interactively copy-to-kill)
|
||||
"Return a longer version string.
|
||||
With prefix argument, copy the string to kill ring.
|
||||
The result contains `ein:version' and either git revision (if
|
||||
the source is in git repository) or elpa version."
|
||||
(interactive "P")
|
||||
(let* ((suffix ; git or elpa
|
||||
(interactive (list t current-prefix-arg))
|
||||
(let* ((version
|
||||
(or (and (ein:git-root-p
|
||||
(concat (file-name-as-directory ein:source-dir) ".."))
|
||||
(let ((default-directory ein:source-dir))
|
||||
(ein:git-revision-dirty)))
|
||||
(and (string-match "/ein-\\([0-9\\.]*\\)/$" ein:source-dir)
|
||||
(match-string 1 ein:source-dir))))
|
||||
(version (if suffix (concat ein:version "-" suffix) ein:version)))
|
||||
(when (called-interactively-p 'interactive)
|
||||
(match-string 1 ein:source-dir)))))
|
||||
(when interactively
|
||||
(message "EIN version is %s" version))
|
||||
(when copy-to-kill
|
||||
(kill-new version))
|
||||
version))
|
||||
|
||||
|
||||
;;; Server attribute getters. These should be moved to ein-open.el
|
||||
|
||||
(defvar *ein:notebook-version* (make-hash-table :test #'equal)
|
||||
|
|
|
@ -123,7 +123,7 @@ callback (`websocket-callback-debug-on-error') is enabled."
|
|||
;; (setq deferred:debug t)
|
||||
(setq request-log-level (quote debug))
|
||||
(lexical-let ((curl-trace (concat temporary-file-directory "curl-trace")))
|
||||
(setq request-curl-options `("--trace-ascii" ,curl-trace))
|
||||
(nconc request-curl-options `("--trace-ascii" ,curl-trace))
|
||||
(add-function :after
|
||||
(symbol-function 'request--curl-callback)
|
||||
(lambda (&rest args)
|
||||
|
@ -228,6 +228,14 @@ callback (`websocket-callback-debug-on-error') is enabled."
|
|||
(apply #'call-process it nil t nil args)
|
||||
(buffer-string))))
|
||||
|
||||
(defsubst ein:dev-packages ()
|
||||
(lexical-let (result)
|
||||
(cl-letf (((symbol-function 'define-package)
|
||||
(lambda (&rest args)
|
||||
(setq result (mapcar (lambda (x) (symbol-name (first x))) (nth 3 args))))))
|
||||
(load "ein-pkg")
|
||||
result)))
|
||||
|
||||
(defun ein:dev-sys-info ()
|
||||
(list
|
||||
"EIN system info"
|
||||
|
@ -253,10 +261,7 @@ callback (`websocket-callback-debug-on-error') is enabled."
|
|||
(ein:dev-dump-vars '("source-dir")))
|
||||
:lib (seq-filter (lambda (info) (plist-get info :path))
|
||||
(mapcar #'ein:dev-sys-info--lib
|
||||
'("websocket" "request" "mumamo"
|
||||
"auto-complete" "popup" "fuzzy" "pos-tip"
|
||||
"python" "python-mode" "markdown-mode"
|
||||
"smartrep" "anything" "helm")))))
|
||||
(ein:dev-packages)))))
|
||||
|
||||
(defun ein:dev-show-sys-info (&optional show-in-buffer)
|
||||
"Show Emacs and library information."
|
||||
|
@ -285,8 +290,7 @@ callback (`websocket-callback-debug-on-error') is enabled."
|
|||
(error (insert (format "`ein:dev-sys-info' produce: %S" err))))
|
||||
(insert "```\n")
|
||||
(goto-char (point-min))
|
||||
(when (fboundp 'markdown-mode)
|
||||
(markdown-mode))
|
||||
(markdown-mode)
|
||||
(pop-to-buffer buffer))))
|
||||
|
||||
(defun ein:dev-print-sys-info (&optional stream)
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
;;; ein-jedi.el --- ein Jedi
|
||||
|
||||
;; Copyright (C) 2012 Takafumi Arakaki
|
||||
|
||||
;; Author: Takafumi Arakaki <aka.tkf at gmail.com>
|
||||
|
||||
;; This file is NOT part of GNU Emacs.
|
||||
|
||||
;; ein-jedi.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-jedi.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-jedi.el.
|
||||
;; If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;;
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'jedi nil t)
|
||||
(require 'jedi-core nil t)
|
||||
|
||||
(require 'ein-completer)
|
||||
(eval-when-compile (require 'ein-connect))
|
||||
(declare-function jedi:complete-request "jedi-core")
|
||||
(declare-function ein:ac-prepare-completion "ein-ac")
|
||||
|
||||
(defvar ein:jedi-dot-complete-sources
|
||||
'(ac-source-jedi-direct ac-source-ein-direct))
|
||||
|
||||
(defun ein:jedi--completer-complete ()
|
||||
(let ((d (deferred:new #'identity)))
|
||||
(ein:completer-complete
|
||||
(ein:get-kernel)
|
||||
(list :complete_reply
|
||||
(cons (lambda (d* &rest args) (deferred:callback-post d* args))
|
||||
d))
|
||||
(apply-partially (lambda (d* err) (deferred:callback-post d* err)) d))
|
||||
d))
|
||||
|
||||
;;;###autoload
|
||||
(defun* ein:jedi-complete (&key (expand ac-expand-on-auto-complete))
|
||||
"Run completion using candidates calculated by EIN and Jedi."
|
||||
(interactive)
|
||||
(lexical-let ((expand expand))
|
||||
(deferred:$
|
||||
(deferred:parallel ; or `deferred:earlier' is better?
|
||||
(jedi:complete-request) ;; need tkf/emacs-jedi submodule
|
||||
(ein:jedi--completer-complete))
|
||||
(deferred:nextc it
|
||||
(lambda (replies)
|
||||
(ein:jedi-complete--prepare-completion replies expand))))))
|
||||
|
||||
(defun ein:jedi-complete--prepare-completion (replies expand)
|
||||
(destructuring-bind
|
||||
(_ ; ignore `jedi:complete-request' what returns.
|
||||
((&key matched_text matches &allow-other-keys) ; :complete_reply
|
||||
_)) ; ignore metadata
|
||||
replies
|
||||
(ein:ac-prepare-completion matches)
|
||||
(let ((ac-expand-on-auto-complete expand))
|
||||
(ac-start))))
|
||||
|
||||
;; Why `ac-start'? See: `jedi:complete'.
|
||||
|
||||
;;;###autoload
|
||||
(defun ein:jedi-dot-complete ()
|
||||
"Insert \".\" and run `ein:jedi-complete'."
|
||||
(interactive)
|
||||
(ein:ac-dot-complete (lambda () (ein:jedi-complete :expand nil))))
|
||||
|
||||
;;;###autoload
|
||||
(defun ein:jedi-setup ()
|
||||
"Setup auto-completion using EIN and Jedi.el_ together.
|
||||
|
||||
Jedi.el_ is a Python auto-completion library for Emacs.
|
||||
To use EIN and Jedi together, add the following in your Emacs setup before loading EIN.::
|
||||
|
||||
(setq ein:completion-backend 'ein:use-ac-jedi-backend)
|
||||
|
||||
.. _Jedi.el: https://github.com/tkf/emacs-jedi"
|
||||
(let ((map ein:connect-mode-map))
|
||||
(define-key map "\C-c\C-i" 'ein:jedi-complete)))
|
||||
|
||||
(provide 'ein-jedi)
|
||||
|
||||
;;; ein-jedi.el ends here
|
|
@ -775,7 +775,6 @@ We need this to have proper behavior for the 'Stop' command in the ein:notebookl
|
|||
(ein:funcall-packed it content metadata))))))))
|
||||
(ein:log 'debug "KERNEL--HANDLE-IOPUB-REPLY: finished"))
|
||||
|
||||
|
||||
;;; Utility functions
|
||||
|
||||
(defun ein:kernel-filename-to-python (kernel filename)
|
||||
|
|
|
@ -162,20 +162,13 @@ This function may raise an error."
|
|||
(set-keymap-parent ein:notebook-multilang-mode-map ess-r-mode-map))))
|
||||
|
||||
(defun ein:ml-lang-setup (kernelspec)
|
||||
(ein:case-equal (ein:$kernelspec-language kernelspec)
|
||||
(("python") (ein:ml-lang-setup-python))
|
||||
(("R") (ein:ml-lang-setup-R))))
|
||||
(funcall (intern (concat "ein:ml-lang-setup-" (ein:$kernelspec-language kernelspec)))))
|
||||
|
||||
;; (defun ein:ml-lang-setup-markdown ()
|
||||
;; "Use `markdown-mode-map'. NOTE: This function is not used now."
|
||||
;; (when (featurep 'markdown-mode)
|
||||
;; (set-keymap-parent ein:notebook-multilang-mode-map markdown-mode-map)))
|
||||
|
||||
;; FIXME: dynamically call ein:ml-lang-setup-LANG using
|
||||
;; `post-command-hook'.
|
||||
;; FIMXE: add more ein:ml-lang-setup-LANG to switch kaymap.
|
||||
|
||||
|
||||
;;; yasnippet
|
||||
|
||||
(defvar ein:ml-yasnippet-parents '(python-mode markdown-mode)
|
||||
|
@ -194,7 +187,6 @@ This function may raise an error."
|
|||
|
||||
(eval-after-load "yasnippet" '(ein:ml-setup-yasnippet))
|
||||
|
||||
|
||||
;;; Imenu Support
|
||||
|
||||
;; Most of this is borrowed from python.el
|
||||
|
|
|
@ -54,7 +54,6 @@
|
|||
(require 'ein-cell-output)
|
||||
(require 'ein-worksheet)
|
||||
(require 'ein-iexec)
|
||||
(require 'ein-jedi)
|
||||
(require 'ein-scratchsheet)
|
||||
(require 'ein-notification)
|
||||
(require 'ein-completer)
|
||||
|
@ -70,7 +69,8 @@
|
|||
(require 'ein-shared-output)
|
||||
(require 'ein-notebooklist)
|
||||
(require 'ein-multilang)
|
||||
|
||||
(require 'poly-ein)
|
||||
|
||||
;;; Configuration
|
||||
|
||||
(make-obsolete-variable 'ein:notebook-discard-output-on-save nil "0.2.0")
|
||||
|
@ -229,7 +229,6 @@ Current buffer for these functions is set to the notebook buffer.")
|
|||
args)))
|
||||
notebook))
|
||||
|
||||
|
||||
;;; Destructor
|
||||
|
||||
(defun ein:notebook-del (notebook)
|
||||
|
@ -305,7 +304,6 @@ will be updated with kernel's cwd."
|
|||
(defun ein:notebook-name-getter (notebook)
|
||||
(cons #'ein:notebook-name notebook))
|
||||
|
||||
|
||||
;;; Open notebook
|
||||
|
||||
(defun ein:notebook-url (notebook)
|
||||
|
@ -327,7 +325,12 @@ will be updated with kernel's cwd."
|
|||
(with-current-buffer (ein:notebook-buffer notebook*)
|
||||
(ein:worksheet-focus-cell))
|
||||
(unless no-pop*
|
||||
(pop-to-buffer (ein:notebook-buffer notebook*)))
|
||||
(with-current-buffer (ein:notebook-buffer notebook*)
|
||||
(if ein:polymode
|
||||
(progn
|
||||
(pm-select-buffer (pm-innermost-span))
|
||||
(pop-to-buffer (pm-span-buffer (pm-innermost-span))))
|
||||
(pop-to-buffer (ein:notebook-buffer notebook*)))))
|
||||
(when (null (plist-member (ein:$notebook-metadata notebook*)
|
||||
:kernelspec))
|
||||
(ein:aif (ein:$notebook-kernelspec notebook*)
|
||||
|
@ -665,15 +668,24 @@ This is equivalent to do ``C-c`` in the console program."
|
|||
|
||||
(defun ein:notebook--worksheet-render (notebook ws)
|
||||
(ein:worksheet-render ws)
|
||||
(with-current-buffer (ein:worksheet-buffer ws)
|
||||
(ein:notebook-mode)
|
||||
(when (ein:$notebook-kernelspec notebook)
|
||||
(ein:ml-lang-setup (ein:$notebook-kernelspec notebook)))
|
||||
;; Now that major-mode is set, set buffer local variables:
|
||||
(ein:worksheet-maybe-disable-undo ws)
|
||||
(ein:notebook--notification-setup notebook)
|
||||
(ein:notebook-setup-kill-buffer-hook)
|
||||
(setq ein:%notebook% notebook)))
|
||||
(save-current-buffer
|
||||
(with-current-buffer (ein:worksheet-buffer ws)
|
||||
(if ein:polymode
|
||||
(poly-ein-mode)
|
||||
;; Changing major mode here is super dangerous as it
|
||||
;; kill-all-local-variables.
|
||||
;; Our saviour has been `ein:deflocal' which applies 'permanent-local
|
||||
;; to variables assigned up to this point, but we ought not rely on it
|
||||
(funcall (ein:notebook-choose-mode))
|
||||
(ein:worksheet-reinstall-undo-hooks ws)
|
||||
(ein:aif (ein:$notebook-kernelspec notebook)
|
||||
(ein:ml-lang-setup it)))
|
||||
(ein:notebook-mode)
|
||||
(ein:notebook--notification-setup notebook)
|
||||
(ein:notebook-setup-kill-buffer-hook)
|
||||
(setq ein:%notebook% notebook)
|
||||
(when ein:polymode
|
||||
(poly-ein-fontify-buffer notebook)))))
|
||||
|
||||
(defun ein:notebook--notification-setup (notebook)
|
||||
(ein:notification-setup
|
||||
|
@ -728,9 +740,7 @@ This is equivalent to do ``C-c`` in the console program."
|
|||
data
|
||||
(setf (ein:$notebook-metadata notebook) metadata)
|
||||
(setf (ein:$notebook-nbformat notebook) nbformat)
|
||||
(setf (ein:$notebook-nbformat-minor notebook) nbformat_minor)
|
||||
;;(setf (ein:$notebook-notebook-name notebook) (plist-get metadata :name))
|
||||
)
|
||||
(setf (ein:$notebook-nbformat-minor notebook) nbformat_minor))
|
||||
(setf (ein:$notebook-worksheets notebook)
|
||||
(cl-case (ein:$notebook-nbformat notebook)
|
||||
(3 (ein:read-nbformat3-worksheets notebook data))
|
||||
|
@ -738,7 +748,7 @@ This is equivalent to do ``C-c`` in the console program."
|
|||
(t (ein:log 'error "nbformat version %s unsupported"
|
||||
(ein:$notebook-nbformat notebook)))))
|
||||
(ein:notebook--worksheet-render notebook
|
||||
(nth 0 (ein:$notebook-worksheets notebook)))
|
||||
(first (ein:$notebook-worksheets notebook)))
|
||||
notebook)
|
||||
|
||||
(defun ein:read-nbformat3-worksheets (notebook data)
|
||||
|
@ -821,7 +831,7 @@ This is equivalent to do ``C-c`` in the console program."
|
|||
(ein:$notebook-notebook-name notebook))))
|
||||
(ein:log 'error "ein:notebook-save-notebook: notebook %s has no buffer!" buf)
|
||||
(setf (ewoc--buffer (ein:worksheet--ewoc
|
||||
(car (ein:$notebook-worksheets notebook))))
|
||||
(first (ein:$notebook-worksheets notebook))))
|
||||
(get-buffer buf))))
|
||||
(condition-case err
|
||||
(with-current-buffer (ein:notebook-buffer notebook)
|
||||
|
@ -879,14 +889,12 @@ This is equivalent to do ``C-c`` in the console program."
|
|||
|
||||
NAME is any non-empty string that does not contain '/' or '\\'."
|
||||
(interactive
|
||||
(list (read-string "Rename notebook: "
|
||||
(list (read-string "Rename to: "
|
||||
(ein:$notebook-notebook-path ein:%notebook%))))
|
||||
(unless (and (string-match ".ipynb" path) (= (match-end 0) (length path)))
|
||||
(unless (and (string-match "\\.ipynb" path) (= (match-end 0) (length path)))
|
||||
(setq path (format "%s.ipynb" path)))
|
||||
(let ((content (ein:content-from-notebook ein:%notebook%))
|
||||
(old-name (ein:$notebook-notebook-name ein:%notebook%)))
|
||||
(ein:log 'info "Renaming notebook at URL %s"
|
||||
(ein:notebook-url ein:%notebook%))
|
||||
(let ((content (ein:content-from-notebook ein:%notebook%)))
|
||||
(ein:log 'verbose "Renaming notebook %s" (ein:notebook-url ein:%notebook%))
|
||||
(ein:content-rename content path #'ein:notebook-rename-success
|
||||
(list ein:%notebook% content))))
|
||||
|
||||
|
@ -912,7 +920,8 @@ NAME is any non-empty string that does not contain '/' or '\\'.
|
|||
(setf (ein:$notebook-notebook-path notebook) (ein:$content-path content))
|
||||
(ein:notebook-put-opened-notebook notebook)
|
||||
(mapc #'ein:worksheet-set-buffer-name
|
||||
(ein:$notebook-worksheets notebook))
|
||||
(append (ein:$notebook-worksheets notebook)
|
||||
(ein:$notebook-scratchsheets notebook)))
|
||||
(ein:log 'info "Notebook renamed to %s." (ein:$content-name content)))
|
||||
|
||||
(defun ein:notebook-close (notebook)
|
||||
|
@ -1384,74 +1393,89 @@ Use simple `python-mode' based notebook mode when MuMaMo is not installed::
|
|||
(with-eval-after-load "ein-smartrep"
|
||||
(ein:smartrep-config ein:notebook-mode-map))
|
||||
|
||||
|
||||
(defmacro ein:notebook--define-key (keymap key defn)
|
||||
"Ideally we could override just the keymap binding with a (string . wrapped) cons pair (as opposed to messing with the DEFN itself), but then describe-minor-mode unhelpfully shows ?? for the keymap commands."
|
||||
`(progn
|
||||
(when (functionp ,defn)
|
||||
(add-function :around (symbol-function ,defn)
|
||||
(lambda (f &rest args)
|
||||
(poly-ein-base (apply f args)))))
|
||||
(define-key ,keymap ,key ,defn)))
|
||||
|
||||
(let ((map ein:notebook-mode-map))
|
||||
(define-key map "\C-ci" 'ein:inspect-object)
|
||||
(define-key map "\C-c'" 'ein:edit-cell-contents)
|
||||
(define-key map "\C-cS" 'ein:worksheet-toggle-slideshow-view)
|
||||
(define-key map "\C-c\C-c" 'ein:worksheet-execute-cell)
|
||||
(define-key map (kbd "M-RET") 'ein:worksheet-execute-cell-and-goto-next)
|
||||
(define-key map (kbd "<M-S-return>")
|
||||
(ein:notebook--define-key map "\C-ci" 'ein:inspect-object)
|
||||
(ein:notebook--define-key map "\C-c'" 'ein:edit-cell-contents)
|
||||
(ein:notebook--define-key map "\C-cS" 'ein:worksheet-toggle-slideshow-view)
|
||||
(ein:notebook--define-key map "\C-c\C-c" 'ein:worksheet-execute-cell)
|
||||
(ein:notebook--define-key map (kbd "M-RET") 'ein:worksheet-execute-cell-and-goto-next)
|
||||
(ein:notebook--define-key map (kbd "<M-S-return>")
|
||||
'ein:worksheet-execute-cell-and-insert-below)
|
||||
(define-key map (kbd "C-c C-'") 'ein:worksheet-turn-on-autoexec)
|
||||
(define-key map "\C-c\C-e" 'ein:worksheet-toggle-output)
|
||||
(define-key map "\C-c\C-v" 'ein:worksheet-set-output-visibility-all)
|
||||
(define-key map "\C-c\C-l" 'ein:worksheet-clear-output)
|
||||
(define-key map (kbd "C-c C-S-l") 'ein:worksheet-clear-all-output)
|
||||
(define-key map (kbd "C-c C-;") 'ein:shared-output-show-code-cell-at-point)
|
||||
(define-key map "\C-c\C-k" 'ein:worksheet-kill-cell)
|
||||
(define-key map "\C-c\M-w" 'ein:worksheet-copy-cell)
|
||||
(define-key map "\C-c\C-w" 'ein:worksheet-copy-cell)
|
||||
(define-key map "\C-c\C-y" 'ein:worksheet-yank-cell)
|
||||
(define-key map "\C-c\C-a" 'ein:worksheet-insert-cell-above)
|
||||
(define-key map "\C-c\C-b" 'ein:worksheet-insert-cell-below)
|
||||
(define-key map "\C-c\C-t" 'ein:worksheet-toggle-cell-type)
|
||||
(define-key map "\C-c\C-d" 'ein:worksheet-toggle-slide-type)
|
||||
(define-key map "\C-c\C-u" 'ein:worksheet-change-cell-type)
|
||||
(define-key map "\C-c\C-s" 'ein:worksheet-split-cell-at-point)
|
||||
(define-key map "\C-c\C-m" 'ein:worksheet-merge-cell)
|
||||
(define-key map "\C-c\C-n" 'ein:worksheet-goto-next-input)
|
||||
(define-key map "\C-c\C-p" 'ein:worksheet-goto-prev-input)
|
||||
(define-key map (kbd "C-<up>") 'ein:worksheet-goto-prev-input)
|
||||
(define-key map (kbd "C-<down>") 'ein:worksheet-goto-next-input)
|
||||
(define-key map (kbd "C-c <up>") 'ein:worksheet-move-cell-up)
|
||||
(define-key map (kbd "C-c <down>") 'ein:worksheet-move-cell-down)
|
||||
(define-key map (kbd "M-<up>") 'ein:worksheet-move-cell-up)
|
||||
(define-key map (kbd "M-<down>") 'ein:worksheet-move-cell-down)
|
||||
(define-key map "\C-c\C-h" 'ein:pytools-request-tooltip-or-help)
|
||||
(define-key map "\C-c\C-i" 'ein:completer-complete)
|
||||
(define-key map (kbd "C-c C-$") 'ein:tb-show)
|
||||
(define-key map "\C-c\C-x" nil)
|
||||
(define-key map "\C-c\C-x\C-l" 'ein:notebook-toggle-latex-fragment)
|
||||
(define-key map "\C-c\C-x\C-r" 'ein:notebook-restart-session-command)
|
||||
(define-key map "\C-c\C-r" 'ein:notebook-reconnect-session-command)
|
||||
(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-c C-#") 'ein:notebook-close)
|
||||
(define-key map (kbd "C-:") 'ein:shared-output-eval-string)
|
||||
(define-key map "\C-c\C-f" 'ein:file-open)
|
||||
(define-key map "\C-c\C-o" 'ein:notebook-open)
|
||||
(define-key map "\C-x\C-s" 'ein:notebook-save-notebook-command)
|
||||
(define-key map "\C-x\C-w" 'ein:notebook-rename-command)
|
||||
(ein:notebook--define-key map (kbd "C-c C-'") 'ein:worksheet-turn-on-autoexec)
|
||||
(ein:notebook--define-key map "\C-c\C-e" 'ein:worksheet-toggle-output)
|
||||
(ein:notebook--define-key map "\C-c\C-v" 'ein:worksheet-set-output-visibility-all)
|
||||
(ein:notebook--define-key map "\C-c\C-l" 'ein:worksheet-clear-output)
|
||||
(ein:notebook--define-key map (kbd "C-c C-S-l") 'ein:worksheet-clear-all-output)
|
||||
(ein:notebook--define-key map (kbd "C-c C-;") 'ein:shared-output-show-code-cell-at-point)
|
||||
(ein:notebook--define-key map "\C-c\C-k" 'ein:worksheet-kill-cell)
|
||||
(ein:notebook--define-key map "\C-c\M-w" 'ein:worksheet-copy-cell)
|
||||
(ein:notebook--define-key map "\C-c\C-w" 'ein:worksheet-copy-cell)
|
||||
(ein:notebook--define-key map "\C-c\C-y" 'ein:worksheet-yank-cell)
|
||||
(ein:notebook--define-key map "\C-c\C-a" 'ein:worksheet-insert-cell-above)
|
||||
(ein:notebook--define-key map "\C-c\C-b" 'ein:worksheet-insert-cell-below)
|
||||
(ein:notebook--define-key map "\C-c\C-t" 'ein:worksheet-toggle-cell-type)
|
||||
(ein:notebook--define-key map "\C-c\C-d" 'ein:worksheet-toggle-slide-type)
|
||||
(ein:notebook--define-key map "\C-c\C-u" 'ein:worksheet-change-cell-type)
|
||||
(ein:notebook--define-key map "\C-c\C-s" 'ein:worksheet-split-cell-at-point)
|
||||
(ein:notebook--define-key map "\C-c\C-m" 'ein:worksheet-merge-cell)
|
||||
(ein:notebook--define-key map "\C-c\C-n" 'ein:worksheet-goto-next-input)
|
||||
(ein:notebook--define-key map "\C-c\C-p" 'ein:worksheet-goto-prev-input)
|
||||
(ein:notebook--define-key map (kbd "C-<up>") 'ein:worksheet-goto-prev-input)
|
||||
(ein:notebook--define-key map (kbd "C-<down>") 'ein:worksheet-goto-next-input)
|
||||
(ein:notebook--define-key map (kbd "C-c <up>") 'ein:worksheet-move-cell-up)
|
||||
(ein:notebook--define-key map (kbd "C-c <down>") 'ein:worksheet-move-cell-down)
|
||||
(ein:notebook--define-key map (kbd "M-<up>") 'ein:worksheet-move-cell-up)
|
||||
(ein:notebook--define-key map (kbd "M-<down>") 'ein:worksheet-move-cell-down)
|
||||
(ein:notebook--define-key map "\C-c\C-h" 'ein:pytools-request-tooltip-or-help)
|
||||
(ein:notebook--define-key map "\C-c\C-i" 'ein:completer-complete)
|
||||
(ein:notebook--define-key map (kbd "C-c C-$") 'ein:tb-show)
|
||||
(ein:notebook--define-key map "\C-c\C-x" nil)
|
||||
(ein:notebook--define-key map "\C-c\C-x\C-l" 'ein:notebook-toggle-latex-fragment)
|
||||
(ein:notebook--define-key map "\C-c\C-x\C-r" 'ein:notebook-restart-session-command)
|
||||
(ein:notebook--define-key map "\C-c\C-r" 'ein:notebook-reconnect-session-command)
|
||||
(ein:notebook--define-key map "\C-c\C-z" 'ein:notebook-kernel-interrupt-command)
|
||||
(ein:notebook--define-key map "\C-c\C-q" 'ein:notebook-kill-kernel-then-close-command)
|
||||
(ein:notebook--define-key map (kbd "C-c C-#") 'ein:notebook-close)
|
||||
(ein:notebook--define-key map (kbd "C-:") 'ein:shared-output-eval-string)
|
||||
(ein:notebook--define-key map "\C-c\C-f" 'ein:file-open)
|
||||
(ein:notebook--define-key map "\C-c\C-o" 'ein:notebook-open)
|
||||
(ein:notebook--define-key map "\C-x\C-s" 'ein:notebook-save-notebook-command)
|
||||
(ein:notebook--define-key map "\C-x\C-w" 'ein:notebook-rename-command)
|
||||
(define-key map "\M-." 'ein:pytools-jump-to-source-command)
|
||||
(define-key map (kbd "C-c C-.") 'ein:pytools-jump-to-source-command)
|
||||
(define-key map "\M-," 'ein:pytools-jump-back-command)
|
||||
(define-key map (kbd "C-c C-,") 'ein:pytools-jump-back-command)
|
||||
(define-key map "\M-p" 'ein:worksheet-previous-input-history)
|
||||
(define-key map "\M-n" 'ein:worksheet-next-input-history)
|
||||
(define-key map (kbd "C-c C-/") 'ein:notebook-scratchsheet-open)
|
||||
(ein:notebook--define-key map "\M-p" 'ein:worksheet-previous-input-history)
|
||||
(ein:notebook--define-key map "\M-n" 'ein:worksheet-next-input-history)
|
||||
(ein:notebook--define-key map (kbd "C-c C-/") 'ein:notebook-scratchsheet-open)
|
||||
;; Worksheets
|
||||
(define-key map (kbd "C-c !") 'ein:worksheet-rename-sheet)
|
||||
(define-key map (kbd "C-c {") 'ein:notebook-worksheet-open-prev-or-last)
|
||||
(define-key map (kbd "C-c }") 'ein:notebook-worksheet-open-next-or-first)
|
||||
(define-key map (kbd "C-c M-{") 'ein:notebook-worksheet-move-prev)
|
||||
(define-key map (kbd "C-c M-}") 'ein:notebook-worksheet-move-next)
|
||||
(define-key map (kbd "C-c +") 'ein:notebook-worksheet-insert-next)
|
||||
(define-key map (kbd "C-c M-+") 'ein:notebook-worksheet-insert-prev)
|
||||
(define-key map (kbd "C-c -") 'ein:notebook-worksheet-delete)
|
||||
(loop for n from 1 to 8
|
||||
do (define-key map (format "\C-c%d" n)
|
||||
(intern (format "ein:notebook-worksheet-open-%sth" n))))
|
||||
(define-key map "\C-c9" 'ein:notebook-worksheet-open-last)
|
||||
(ein:notebook--define-key map (kbd "C-c !") 'ein:worksheet-rename-sheet)
|
||||
(ein:notebook--define-key map (kbd "C-c {") 'ein:notebook-worksheet-open-prev-or-last)
|
||||
(ein:notebook--define-key map (kbd "C-c }") 'ein:notebook-worksheet-open-next-or-first)
|
||||
(ein:notebook--define-key map (kbd "C-c M-{") 'ein:notebook-worksheet-move-prev)
|
||||
(ein:notebook--define-key map (kbd "C-c M-}") 'ein:notebook-worksheet-move-next)
|
||||
(ein:notebook--define-key map (kbd "C-c +") 'ein:notebook-worksheet-insert-next)
|
||||
(ein:notebook--define-key map (kbd "C-c M-+") 'ein:notebook-worksheet-insert-prev)
|
||||
(ein:notebook--define-key map (kbd "C-c -") 'ein:notebook-worksheet-delete)
|
||||
(ein:notebook--define-key map "\C-c1" 'ein:notebook-worksheet-open-1th)
|
||||
(ein:notebook--define-key map "\C-c2" 'ein:notebook-worksheet-open-2th)
|
||||
(ein:notebook--define-key map "\C-c3" 'ein:notebook-worksheet-open-3th)
|
||||
(ein:notebook--define-key map "\C-c4" 'ein:notebook-worksheet-open-4th)
|
||||
(ein:notebook--define-key map "\C-c5" 'ein:notebook-worksheet-open-5th)
|
||||
(ein:notebook--define-key map "\C-c6" 'ein:notebook-worksheet-open-6th)
|
||||
(ein:notebook--define-key map "\C-c7" 'ein:notebook-worksheet-open-7th)
|
||||
(ein:notebook--define-key map "\C-c8" 'ein:notebook-worksheet-open-8th)
|
||||
(ein:notebook--define-key map "\C-c9" 'ein:notebook-worksheet-open-last)
|
||||
;; Menu
|
||||
(easy-menu-define ein:notebook-menu map "EIN Notebook Mode Menu"
|
||||
`("EIN Notebook"
|
||||
|
@ -1597,24 +1621,17 @@ watch the fireworks!"
|
|||
;; It is executed after toggling the mode, and before running MODE-hook.
|
||||
|
||||
(when ein:notebook-mode
|
||||
(funcall (ein:notebook-choose-mode))
|
||||
(case ein:completion-backend
|
||||
(ein:use-ac-backend
|
||||
(define-key ein:notebook-mode-map "." 'ein:notebook-ac-dot-complete)
|
||||
(auto-complete-mode))
|
||||
(ein:use-ac-jedi-backend
|
||||
(define-key ein:notebook-mode-map "." 'ein:notebook-ac-dot-complete)
|
||||
(ein:notebook--define-key ein:notebook-mode-map "." 'ein:notebook-ac-dot-complete)
|
||||
(auto-complete-mode))
|
||||
(ein:use-company-backend
|
||||
(define-key ein:notebook-mode-map "." nil)
|
||||
(company-mode))
|
||||
(ein:use-company-jedi-backend
|
||||
(define-key ein:notebook-mode-map "." nil)
|
||||
(ein:notebook--define-key ein:notebook-mode-map "." nil)
|
||||
(company-mode)))
|
||||
(ein:aif ein:helm-kernel-history-search-key
|
||||
(define-key ein:notebook-mode-map it 'helm-ein-kernel-history))
|
||||
(ein:notebook--define-key ein:notebook-mode-map it 'helm-ein-kernel-history))
|
||||
(ein:aif ein:anything-kernel-history-search-key
|
||||
(define-key ein:notebook-mode-map it 'anything-ein-kernel-history))
|
||||
(ein:notebook--define-key ein:notebook-mode-map it 'anything-ein-kernel-history))
|
||||
(setq indent-tabs-mode nil) ;; Being T causes problems with Python code.
|
||||
(when (and (featurep 'eldoc) ein:enable-eldoc-support)
|
||||
(add-function :before-until (local 'eldoc-documentation-function)
|
||||
|
@ -1622,8 +1639,7 @@ watch the fireworks!"
|
|||
(eldoc-mode))
|
||||
(ein:worksheet-imenu-setup)
|
||||
(when ein:use-smartrep
|
||||
(require 'ein-smartrep))
|
||||
(ein:worksheet-reinstall-which-cell-hook)))
|
||||
(require 'ein-smartrep))))
|
||||
|
||||
;; To avoid MuMaMo to discard `ein:notebook-mode', make it
|
||||
;; permanent local.
|
||||
|
|
|
@ -325,7 +325,7 @@ Generated by `ein:header-line-define-mouse-commands'" slot)
|
|||
As `header-line-format' is buffer local variable, it must be set
|
||||
for each chunk when in
|
||||
See also `ein:ac-setup-maybe'."
|
||||
(and (ein:eval-if-bound 'ein:%notebook%)
|
||||
(and ein:notebook-mode
|
||||
(ein:eval-if-bound 'mumamo-multi-major-mode)
|
||||
(setq header-line-format ein:header-line-format)))
|
||||
(add-hook 'after-change-major-mode-hook 'ein:header-line-setup-maybe)
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
(define-package "ein"
|
||||
"0.15.0"
|
||||
"0.16.0"
|
||||
"Emacs IPython Notebook"
|
||||
'((websocket "1.7")
|
||||
(auto-complete "1.4.0")
|
||||
(request "0.3")
|
||||
(deferred "0.5")
|
||||
(cl-generic "0.3")
|
||||
(polymode "0.1.5")
|
||||
(markdown-mode "2.3")
|
||||
(dash "2.13.0")
|
||||
(s "1.11.0")
|
||||
(skewer-mode "1.6.2")))
|
||||
|
|
|
@ -264,25 +264,32 @@ When the prefix argument ``C-u`` is given, open the source code
|
|||
in the other window. You can explicitly specify the object by
|
||||
selecting it."
|
||||
(interactive "P")
|
||||
(let ((kernel (ein:get-kernel))
|
||||
(object (ein:object-at-point)))
|
||||
(assert (ein:kernel-live-p kernel) nil "Kernel is not ready.")
|
||||
(assert object nil "Object at point not found.")
|
||||
(ein:pytools-jump-to-source kernel object other-window
|
||||
(when ein:propagate-connect
|
||||
(ein:get-notebook)))))
|
||||
(if poly-ein-mode
|
||||
(cl-letf (((symbol-function 'xref--prompt-p) #'ignore))
|
||||
(if other-window
|
||||
(call-interactively #'xref-find-definitions-other-window)
|
||||
(call-interactively #'xref-find-definitions)))
|
||||
(let ((kernel (ein:get-kernel))
|
||||
(object (ein:object-at-point)))
|
||||
(assert (ein:kernel-live-p kernel) nil "Kernel is not ready.")
|
||||
(assert object nil "Object at point not found.")
|
||||
(ein:pytools-jump-to-source kernel object other-window
|
||||
(when ein:propagate-connect
|
||||
(ein:get-notebook))))))
|
||||
|
||||
(defun ein:pytools-jump-back-command (&optional other-window)
|
||||
"Go back to the point where `ein:pytools-jump-to-source-command'
|
||||
is executed last time. When the prefix argument ``C-u`` is
|
||||
given, open the last point in the other window."
|
||||
(interactive "P")
|
||||
(when (ein:aand (car ein:pytools-jump-stack)
|
||||
(equal (point) (marker-position it)))
|
||||
(setq ein:pytools-jump-stack (cdr ein:pytools-jump-stack)))
|
||||
(ein:aif (car ein:pytools-jump-stack)
|
||||
(ein:goto-marker it other-window)
|
||||
(ein:log 'info "Nothing on stack.")))
|
||||
(if poly-ein-mode
|
||||
(call-interactively #'xref-pop-marker-stack)
|
||||
(when (ein:aand (car ein:pytools-jump-stack)
|
||||
(equal (point) (marker-position it)))
|
||||
(setq ein:pytools-jump-stack (cdr ein:pytools-jump-stack)))
|
||||
(ein:aif (car ein:pytools-jump-stack)
|
||||
(ein:goto-marker it other-window)
|
||||
(ein:log 'info "Nothing on stack."))))
|
||||
|
||||
(define-obsolete-function-alias
|
||||
'ein:pytools-eval-string-internal
|
||||
|
|
|
@ -27,25 +27,18 @@
|
|||
|
||||
;;; Code:
|
||||
|
||||
(defcustom ein:completion-backend 'ein:use-ac-backend
|
||||
"Determines which completion backend to use in opened EIN notebooks.
|
||||
(defcustom ein:completion-backend 'ein:use-none-backend
|
||||
"EIN defaults to your individual company-mode or auto-complete-mode configuration. Change this setting to gather completions from the jupyter server::
|
||||
|
||||
After changing the value of this variable it is recommended that
|
||||
you restart Emacs. The available completion backends are::
|
||||
|
||||
* ein:use-ac-backend : Use auto-complete with IPython's builtin completion engine.
|
||||
* ein:use-ac-jedi-backend : Use auto-complete with the Jedi backend.
|
||||
* ein:use-company-backend : Use company-mode with IPython's builtin completion engine.
|
||||
* ein:use-company-jedi-backends : Use company-mode with the Jedi backend (currently not implemented).
|
||||
* ein:use-none-backend: Avoid autocomplete altogether
|
||||
* ein:use-none-backend: local completions only (configured outside EIN)
|
||||
* ein:use-company-backend: company-style remote completions (elpy takes precedence)
|
||||
* ein:use-ac-backend: deprecated auto-complete remote completions
|
||||
"
|
||||
:type '(choice
|
||||
(const ein:use-ac-backend)
|
||||
(const ein:use-ac-jedi-backend)
|
||||
(const ein:use-none-backend)
|
||||
(const ein:use-company-backend)
|
||||
(const ein:use-company-jedi-backend)
|
||||
(const ein:use-none-backend))
|
||||
:group 'ein-completion)
|
||||
(const ein:use-ac-backend))
|
||||
:group 'ein)
|
||||
|
||||
(provide 'ein-subpackages)
|
||||
|
||||
|
|
|
@ -71,6 +71,9 @@ while maintaining the undo list for the current buffer."
|
|||
((= (length head) 1) `(if ,(car head) ,rest))
|
||||
(t `(let (,head) (if ,(car head) ,rest)))))))
|
||||
|
||||
(defvar ein:local-variables '()
|
||||
"Modified by `ein:deflocal'")
|
||||
|
||||
(defmacro ein:deflocal (name &optional initvalue docstring)
|
||||
"Define permanent buffer local variable named NAME.
|
||||
INITVALUE and DOCSTRING are passed to `defvar'."
|
||||
|
@ -79,7 +82,8 @@ INITVALUE and DOCSTRING are passed to `defvar'."
|
|||
`(progn
|
||||
(defvar ,name ,initvalue ,docstring)
|
||||
(make-variable-buffer-local ',name)
|
||||
(put ',name 'permanent-local t)))
|
||||
(put ',name 'permanent-local t)
|
||||
(setq ein:local-variables (append ein:local-variables '(,name)))))
|
||||
|
||||
(defmacro ein:with-read-only-buffer (buffer &rest body)
|
||||
(declare (indent 1))
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
(require 'ein-utils)
|
||||
(require 'ein-cell)
|
||||
(require 'ein-kill-ring)
|
||||
(require 'poly-ein)
|
||||
|
||||
|
||||
;;; Configuration
|
||||
|
||||
;; (define-obsolete-variable-alias
|
||||
|
@ -57,10 +57,8 @@
|
|||
:type 'boolean
|
||||
:group 'ein)
|
||||
|
||||
|
||||
|
||||
(ein:deflocal buffer-local-enable-undo t
|
||||
"Buffer local variable with activating undo accounting. Should not modify.")
|
||||
"Buffer local variable activating undo accounting. Should not modify.")
|
||||
|
||||
(ein:deflocal ein:%cell-lengths% '()
|
||||
"Buffer local variable with buffer-undo-list's current knowledge of cell lengths.")
|
||||
|
@ -73,7 +71,10 @@
|
|||
(intern (substring (slot-value cell 'cell-id) 0 5)))
|
||||
|
||||
(defun ein:worksheet--which-cell-hook (change-beg change-end prev-len)
|
||||
(when (and (not (null buffer-undo-list)) (listp buffer-undo-list))
|
||||
"Hook important for undo thats runs for everything we type (an after-change-functions hook).
|
||||
|
||||
Normalize `buffer-undo-list' by removing extraneous details, and update the ein:%which-cell% ledger that associates changes in `buffer-undo-list' with individual cells."
|
||||
(when (and buffer-undo-list (listp buffer-undo-list))
|
||||
(setq buffer-undo-list (cl-delete-if (lambda (u) (or (numberp u) (and (consp u) (markerp (car u))))) buffer-undo-list))
|
||||
(let ((fill (- (length buffer-undo-list) (length ein:%which-cell%))))
|
||||
(if (< fill 0)
|
||||
|
@ -181,12 +182,16 @@
|
|||
(setq ein:%which-cell% (-replace old-cell-id new-cell-id ein:%which-cell%)))
|
||||
(let ((fill (- (length buffer-undo-list) (length ein:%which-cell%))))
|
||||
(if (> (abs fill) 1)
|
||||
;; TODO: reset ein:%which-cell% when major mode gets swapped
|
||||
(progn
|
||||
(let ((msg (format "Undo failure diagnostic %s %s | %s"
|
||||
buffer-undo-list ein:%which-cell% fill)))
|
||||
buffer-undo-list ein:%which-cell% fill))
|
||||
(pm-allow-post-command-hook nil))
|
||||
(setq ein:worksheet-enable-undo nil)
|
||||
(ein:worksheet-maybe-disable-undo ein:%worksheet%)
|
||||
(ein:worksheet-undo-setup ein:%worksheet%)
|
||||
(when pm/polymode
|
||||
(dolist (b (eieio-oref pm/polymode '-buffers))
|
||||
(when (buffer-live-p b)
|
||||
(poly-ein-copy-state (ein:worksheet--get-buffer ein:%worksheet%) b))))
|
||||
(ein:display-warning msg :error)
|
||||
(error "ein:worksheet--jigger-undo-list: aborting")))
|
||||
(if (< fill 0)
|
||||
|
@ -371,11 +376,29 @@
|
|||
|
||||
(cl-defmethod ein:worksheet--get-buffer ((ws ein:worksheet))
|
||||
(or (ein:worksheet-buffer ws)
|
||||
(generate-new-buffer (ein:worksheet--buffer-name ws))))
|
||||
(with-current-buffer (generate-new-buffer (ein:worksheet--buffer-name ws))
|
||||
(let ((buffer-undo-list t))
|
||||
(setf (ein:worksheet--ewoc ws)
|
||||
(ein:ewoc-create 'ein:worksheet-pp
|
||||
(ein:propertize-read-only "\n")
|
||||
nil t))
|
||||
(current-buffer)))))
|
||||
|
||||
(cl-defmethod ein:worksheet-set-buffer-name ((ws ein:worksheet))
|
||||
(ein:with-live-buffer (ein:worksheet-buffer ws)
|
||||
(rename-buffer (ein:worksheet--buffer-name ws) t)))
|
||||
(dolist (b (or (and pm/polymode (eieio-oref pm/polymode '-buffers))
|
||||
(list (current-buffer))))
|
||||
(ein:with-live-buffer b
|
||||
(rename-buffer
|
||||
(let ((simple-name (ein:worksheet--buffer-name ein:%worksheet%)))
|
||||
(if (and pm/polymode (not (eq (pm-base-buffer) (current-buffer))))
|
||||
(let ((chunkmode (nth 3 (pm-innermost-span))))
|
||||
(format "%s[%s]" simple-name
|
||||
(replace-regexp-in-string
|
||||
"poly-\\|-mode" ""
|
||||
(symbol-name
|
||||
(pm--get-existing-mode (eieio-oref chunkmode 'mode))))))
|
||||
simple-name)))))))
|
||||
|
||||
(cl-defmethod ein:worksheet-set-modified-p ((ws ein:worksheet) dirty)
|
||||
(ein:with-live-buffer (ein:worksheet-buffer ws)
|
||||
|
@ -391,36 +414,35 @@
|
|||
(not (ein:worksheet--show-slide-data-p ws)))
|
||||
(ein:worksheet-render ws)))
|
||||
|
||||
(cl-defmethod ein:worksheet-maybe-disable-undo ((ws ein:worksheet))
|
||||
(cl-defmethod ein:worksheet-undo-setup ((ws ein:worksheet))
|
||||
(with-current-buffer (ein:worksheet--get-buffer ws)
|
||||
(setq buffer-local-enable-undo ein:worksheet-enable-undo)
|
||||
(let ((undo-binding (key-binding (kbd "C-/"))))
|
||||
(if ein:worksheet-enable-undo
|
||||
(if (eq undo-binding 'undo)
|
||||
(setq buffer-local-enable-undo t)
|
||||
(if buffer-local-enable-undo
|
||||
(unless (eq undo-binding 'undo)
|
||||
(setq buffer-local-enable-undo nil)
|
||||
(ein:display-warning-once (format "Disabling undo for %s" undo-binding)))
|
||||
(setq buffer-local-enable-undo nil)))
|
||||
(when (not buffer-local-enable-undo)
|
||||
(setq buffer-undo-list t))))
|
||||
(ein:display-warning-once (format "Disabling undo for %s" undo-binding)))))
|
||||
(ein:worksheet-reinstall-undo-hooks ws)
|
||||
(if buffer-local-enable-undo
|
||||
(progn
|
||||
(setq buffer-undo-list nil)
|
||||
(setq ein:%which-cell% nil)
|
||||
(setq ein:%cell-lengths% nil))
|
||||
(setq buffer-undo-list t))))
|
||||
|
||||
(cl-defmethod ein:worksheet-reinstall-undo-hooks ((ws ein:worksheet))
|
||||
(with-current-buffer (ein:worksheet--get-buffer ws)
|
||||
(if buffer-local-enable-undo
|
||||
(add-hook 'after-change-functions 'ein:worksheet--which-cell-hook nil t)
|
||||
(remove-hook 'after-change-functions 'ein:worksheet--which-cell-hook t))))
|
||||
|
||||
(cl-defmethod ein:worksheet-render ((ws ein:worksheet))
|
||||
(with-current-buffer (ein:worksheet--get-buffer ws)
|
||||
(setq ein:%worksheet% ws)
|
||||
|
||||
(when buffer-local-enable-undo
|
||||
(setq buffer-undo-list nil)
|
||||
(setq ein:%which-cell% nil)
|
||||
(setq ein:%cell-lengths% nil))
|
||||
|
||||
(ein:worksheet-reinstall-which-cell-hook)
|
||||
(let ((inhibit-read-only t))
|
||||
(erase-buffer)
|
||||
(let ((ewoc (let ((buffer-undo-list t))
|
||||
(ein:ewoc-create 'ein:worksheet-pp
|
||||
(ein:propertize-read-only "\n")
|
||||
nil t)))
|
||||
(cells (ein:worksheet--saved-cells ws)))
|
||||
(setf (ein:worksheet--ewoc ws) ewoc)
|
||||
(ein:worksheet-undo-setup ws)
|
||||
(let ((inhibit-read-only t)
|
||||
(ewoc (ein:worksheet--ewoc ws)))
|
||||
(let ((cells (ein:worksheet--saved-cells ws)))
|
||||
(if cells
|
||||
(let ((buffer-undo-list t))
|
||||
(mapc (lambda (c)
|
||||
|
@ -641,8 +663,9 @@ kill-ring of Emacs (kill-ring for texts)."
|
|||
(deactivate-mark)))))
|
||||
(let ((cells (mapcar
|
||||
(lambda (c)
|
||||
(ein:cell-deactivate (ein:cell-copy c))) cells)))
|
||||
(ein:log 'info "%s cells are copied." (length cells))
|
||||
(ein:cell-deactivate (ein:cell-copy c)))
|
||||
cells)))
|
||||
(ein:log 'info "%s cells are copied." (length cells))
|
||||
(ein:kill-new cells)))
|
||||
|
||||
(defun ein:worksheet-insert-clone (ws cell pivot up)
|
||||
|
@ -857,16 +880,18 @@ If prefix is given, merge current cell into next cell."
|
|||
t))
|
||||
(unless next
|
||||
(setq cell (ein:cell-prev cell))
|
||||
(unless cell (error "No previous cell"))
|
||||
(ein:cell-goto cell))
|
||||
(let* ((next-cell (ein:cell-next cell))
|
||||
(head (ein:cell-get-text cell)))
|
||||
(assert next-cell nil "No cell to merge.")
|
||||
(ein:worksheet-delete-cell ws cell)
|
||||
(save-excursion
|
||||
(goto-char (ein:cell-input-pos-min next-cell))
|
||||
(insert head "\n"))
|
||||
(when focus (ein:cell-goto next-cell))))
|
||||
(if cell
|
||||
(ein:cell-goto cell)
|
||||
(message "No previous cell")))
|
||||
(when cell
|
||||
(let* ((next-cell (ein:cell-next cell))
|
||||
(head (ein:cell-get-text cell)))
|
||||
(assert next-cell nil "No cell to merge.")
|
||||
(ein:worksheet-delete-cell ws cell)
|
||||
(save-excursion
|
||||
(goto-char (ein:cell-input-pos-min next-cell))
|
||||
(insert head "\n"))
|
||||
(when focus (ein:cell-goto next-cell)))))
|
||||
|
||||
|
||||
;;; Cell selection.
|
||||
|
@ -901,7 +926,7 @@ When NTH is specified, return NTH cell. Note that this function is
|
|||
(defun ein:worksheet-goto-input (ewoc-node up)
|
||||
(ein:aif (ein:worksheet-next-input-cell ewoc-node up)
|
||||
(ein:cell-goto it)
|
||||
(error "No %s input!" (if up "previous" "next"))))
|
||||
(message "No %s input" (if up "previous" "next"))))
|
||||
|
||||
(defun ein:worksheet-goto-next-input (ewoc-node)
|
||||
(interactive (list (and (ein:worksheet--get-ws-or-error)
|
||||
|
@ -963,7 +988,7 @@ It is set in `ein:notebook-multilang-mode'."
|
|||
(setq clone (ein:worksheet-insert-clone ws cell pivot-cell (if up "above" "below")))
|
||||
(ein:cell-goto clone)
|
||||
(oset ws :dirty t))
|
||||
(error "No %s cell" (if up "previous" "next"))))
|
||||
(message "No %s cell" (if up "previous" "next"))))
|
||||
|
||||
(defun ein:worksheet-move-cell-up (ws cell)
|
||||
(interactive (list (ein:worksheet--get-ws-or-error)
|
||||
|
@ -1293,12 +1318,6 @@ function."
|
|||
for name = (ein:join-str "" (append sharps (list " " text)))
|
||||
collect (cons name (ein:cell-input-pos-min cell))))
|
||||
|
||||
(defun ein:worksheet-reinstall-which-cell-hook ()
|
||||
"Fontify clobbers the which-cell hook."
|
||||
(if buffer-local-enable-undo
|
||||
(add-hook 'after-change-functions 'ein:worksheet--which-cell-hook t t)
|
||||
(remove-hook 'after-change-functions 'ein:worksheet--which-cell-hook t)))
|
||||
|
||||
(defun ein:worksheet-imenu-setup ()
|
||||
"Called via notebook mode hooks."
|
||||
(setq imenu-create-index-function #'ein:worksheet-imenu-create-index))
|
||||
|
|
57
lisp/ein.el
57
lisp/ein.el
|
@ -24,57 +24,12 @@
|
|||
|
||||
;;; Commentary:
|
||||
|
||||
;; ==================================
|
||||
;; EIN -- Emacs IPython Notebook
|
||||
;; ==================================
|
||||
|
||||
;; --- or **E**\ IN **I**\ s not only for **N**\ otebooks.
|
||||
|
||||
;; EIN works with IPython 2.x_, 3.x_, and Juptyer_! Note that remote and
|
||||
;; password protected logins are working with IPython 3.x, but have not been
|
||||
;; tested with Jupyter.
|
||||
|
||||
;; .. note:: The code has been stable enough for my day to day work, but there are
|
||||
;; no guarantees for the safety for your notebook data. Please make sure
|
||||
;; that you backup and backup often!
|
||||
|
||||
;; .. _2.x: http://ipython.org/ipython-doc/2/index.html
|
||||
;; .. _3.x: http://ipython.org/ipython-doc/3/index.html
|
||||
;; .. _Jupyter: http://jupyter.org
|
||||
|
||||
;; Features
|
||||
;; ========
|
||||
|
||||
;; The Emacs IPython Notebook (EIN) provides a client for the IPython v2.x and
|
||||
;; 3.x notebooks and an integrated REPL (like SLIME_) in Emacs. EIN makes
|
||||
;; notebook editing very powerful by allowing you to use any Emacs features, it
|
||||
;; also expose IPython features such as code evaluation, object inspection and
|
||||
;; code completion to the Emacs side. These features can be accessed anywhere
|
||||
;; in Emacs and improve Python code editing and reading in Emacs.
|
||||
|
||||
;; .. _SLIME: http://common-lisp.net/project/slime/
|
||||
|
||||
;; Highlighted features:
|
||||
|
||||
;; * Copy/paste cells, even to/from different notebooks.
|
||||
;; * Console integration: You can easily connect to a kernel via the console
|
||||
;; application. This enables you to start debugging in the same kernel. It is
|
||||
;; even possible to connect to a console over ssh.
|
||||
;; * An IPython kernel can be "connected" to any buffer. This enables you to
|
||||
;; evaluate a buffer or buffer region using the same kernel as the notebook.
|
||||
;; Notebook goodies such as tooltip help, help browser and code completion are
|
||||
;; available in these buffers.
|
||||
;; * Jump to definition (go to the definition by hitting ``M-.`` over an object).
|
||||
|
||||
;; Other notebook features:
|
||||
|
||||
;; * Inline images
|
||||
;; * Auto/manual-completion
|
||||
;; * Popup (tooltip) help
|
||||
;; * Syntax highlighting in each cell types (Python/Markdown)
|
||||
;; * Help browser (opens when executing ``function?``)
|
||||
;; * Traceback viewer
|
||||
|
||||
;; Emacs IPython Notebook (EIN) lets you edit and run Jupyter_ (formerly IPython)
|
||||
;; notebooks within Emacs. It channels all the power of Emacs without the
|
||||
;; idiosyncrasies of in-browser editing.
|
||||
;;
|
||||
;; EIN was originally written by tkf_. More `complete documentation`_ is available.
|
||||
;;
|
||||
|
||||
;;; Code:
|
||||
|
||||
|
|
299
lisp/poly-ein.el
Normal file
299
lisp/poly-ein.el
Normal file
|
@ -0,0 +1,299 @@
|
|||
(add-to-list 'features 'poly-lock) ;; skirt poly-lock
|
||||
(require 'polymode)
|
||||
(require 'ein-cell)
|
||||
(require 'jit-lock)
|
||||
|
||||
(defmacro poly-ein-base (&rest body)
|
||||
"Copy the undo accounting to the base buffer and run BODY in it."
|
||||
`(let ((base-buffer (pm-base-buffer))
|
||||
(derived-buffer (current-buffer))
|
||||
(pm-allow-post-command-hook nil)
|
||||
(pm-initialization-in-progress t))
|
||||
(poly-ein--set-buffer derived-buffer base-buffer)
|
||||
(condition-case err
|
||||
(prog1 (progn ,@body)
|
||||
(poly-ein--set-buffer base-buffer derived-buffer))
|
||||
(error (message "%s" (error-message-string err))
|
||||
(poly-ein--set-buffer base-buffer derived-buffer)))))
|
||||
|
||||
(defcustom ein:polymode nil
|
||||
"Turn off hacky major mode emulations, turn on polymode."
|
||||
:type 'boolean
|
||||
:group 'ein)
|
||||
|
||||
(defclass pm-inner-overlay-chunkmode (pm-inner-auto-chunkmode)
|
||||
()
|
||||
"Inner chunkmode delimited by cell overlays.")
|
||||
|
||||
(cl-defmethod pm-get-span ((cm pm-inner-overlay-chunkmode) &optional pos)
|
||||
"Return a list of the form (TYPE POS-START POS-END RESULT-CM).
|
||||
|
||||
TYPE can be 'body, nil."
|
||||
(poly-ein-base
|
||||
(setq pos (or pos (point)))
|
||||
;; Assume: ein:worksheet-get-current-cell always returns non-nil
|
||||
(let ((result-cm cm)
|
||||
(span `(nil ,(point-min) ,(point-min)))
|
||||
(cell (ein:worksheet-get-current-cell :pos pos :noerror nil)))
|
||||
;; Change :mode if necessary
|
||||
(ein:and-let* ((lang
|
||||
(condition-case err
|
||||
(ein:$kernelspec-language
|
||||
(ein:$notebook-kernelspec
|
||||
(ein:get-notebook)))
|
||||
(error (message "%s: defaulting language to python"
|
||||
(error-message-string err))
|
||||
"python")))
|
||||
(mode
|
||||
(pm-get-mode-symbol-from-name
|
||||
(cond ((ein:codecell-p cell) lang)
|
||||
((ein:markdowncell-p cell) "markdown")
|
||||
(t "fundamental"))))
|
||||
((not (equal mode (ein:oref-safe cm :mode)))))
|
||||
(setq result-cm
|
||||
(loop for ocm in (eieio-oref pm/polymode '-auto-innermodes)
|
||||
when (equal mode (ein:oref-safe ocm :mode))
|
||||
return ocm
|
||||
finally return (let ((new-mode (clone cm :mode mode)))
|
||||
(object-add-to-list pm/polymode '-auto-innermodes
|
||||
new-mode)
|
||||
new-mode))))
|
||||
;; Span is a zebra pattern of "body" (within input cell) and "nil"
|
||||
;; (outside input cell). Decide boundaries of span and return it.
|
||||
(let ((rel (poly-ein--relative-to-input pos cell)))
|
||||
(cond ((zerop rel)
|
||||
(setq span `(body
|
||||
,(ein:cell-input-pos-min cell)
|
||||
,(1+ (ein:cell-input-pos-max cell)))))
|
||||
((< rel 0)
|
||||
(setq span `(nil
|
||||
,(or (ein:aand (ein:cell-prev cell)
|
||||
(1+ (ein:cell-input-pos-max it)))
|
||||
(point-min))
|
||||
,(ein:cell-input-pos-min cell))))
|
||||
(t
|
||||
(setq span `(nil
|
||||
,(1+ (ein:cell-input-pos-max cell))
|
||||
,(or (ein:aand (ein:cell-next cell)
|
||||
(ein:cell-input-pos-min it))
|
||||
(point-max)))))))
|
||||
(append span (list result-cm)))))
|
||||
|
||||
(defun poly-ein-fontify-buffer (notebook)
|
||||
"Called from `ein:notebook--worksheet-render'"
|
||||
(with-current-buffer (ein:notebook-buffer notebook)
|
||||
(save-excursion
|
||||
(pm-map-over-spans
|
||||
(lambda (span)
|
||||
(condition-case err
|
||||
(let ((syntax-propertize--done (point-min)))
|
||||
(jit-lock-function (nth 1 span)))
|
||||
(error (ein:log 'warn "ein:notebook--worksheet-render: %s"
|
||||
(error-message-string err)))))))))
|
||||
|
||||
(defun poly-ein--relative-to-input (pos cell)
|
||||
"Return -1 if POS before input, 1 if after input, 0 if within"
|
||||
(let* ((input-pos-min (ein:cell-input-pos-min cell))
|
||||
(input-pos-max (ein:cell-input-pos-max cell)))
|
||||
(cond ((< pos input-pos-min) -1)
|
||||
((> pos input-pos-max) 1)
|
||||
(t 0))))
|
||||
|
||||
(defvar jit-lock-start)
|
||||
(defvar jit-lock-end)
|
||||
(defun poly-ein--hem-jit-lock (start end _old-len)
|
||||
(when (and poly-ein-mode (not pm-initialization-in-progress))
|
||||
(let ((range (pm-innermost-range (or start (point)))))
|
||||
(setq jit-lock-start (max jit-lock-start (car range)))
|
||||
(setq jit-lock-end (min jit-lock-end (cdr range))))))
|
||||
|
||||
(defun poly-ein-undo-damage (type)
|
||||
(remove-hook 'after-change-functions 'polymode-flush-syntax-ppss-cache t)
|
||||
(add-hook 'jit-lock-after-change-extend-region-functions #'poly-ein--hem-jit-lock t t)
|
||||
(setq jit-lock-contextually nil) ; else recenter font-lock-fontify-keywords-region
|
||||
(setq jit-lock-context-unfontify-pos nil)
|
||||
(if (eq type 'host)
|
||||
(setq syntax-propertize-function nil)
|
||||
(setq syntax-propertize-function pm--syntax-propertize-function-original)
|
||||
(add-function :before-until (local 'syntax-propertize-function)
|
||||
#'poly-ein--unrelated-span)
|
||||
(add-function :filter-args (local 'syntax-propertize-function)
|
||||
#'poly-ein--span-start-end)))
|
||||
|
||||
(defun poly-ein-init-input-cell (_type)
|
||||
(mapc (lambda (f) (add-to-list 'after-change-functions f))
|
||||
(buffer-local-value 'after-change-functions (pm-base-buffer)))
|
||||
(poly-ein-copy-state (pm-base-buffer) (current-buffer))
|
||||
(ein:notebook-mode))
|
||||
|
||||
(defcustom pm-host/ein
|
||||
(pm-host-chunkmode :name "ein"
|
||||
:init-functions '(poly-ein-undo-damage))
|
||||
"EIN host chunkmode"
|
||||
:group 'poly-hostmodes
|
||||
:type 'object)
|
||||
|
||||
(defcustom pm-inner/ein-input-cell
|
||||
(pm-inner-overlay-chunkmode :name "ein-input-cell"
|
||||
:init-functions '(poly-ein-undo-damage poly-ein-init-input-cell))
|
||||
"EIN input cell."
|
||||
:group 'poly-innermodes
|
||||
:type 'object)
|
||||
|
||||
(defcustom poly-ein-mode-hook nil
|
||||
"Hook for poly-ein-mode"
|
||||
:type 'hook :group 'poly-ein)
|
||||
|
||||
;;;###autoload (autoload 'poly-ein-mode "poly-ein")
|
||||
(define-polymode poly-ein-mode
|
||||
:lighter " PM-ipynb"
|
||||
:hostmode 'pm-host/ein
|
||||
:innermodes '(pm-inner/ein-input-cell))
|
||||
|
||||
(defun poly-ein-copy-state (src-buf dest-buf)
|
||||
"Consolidate fragility here."
|
||||
(unless (eq src-buf dest-buf)
|
||||
(with-current-buffer dest-buf (remove-overlays nil nil 'face 'ein:cell-input-area))
|
||||
(mapc (lambda (ol)
|
||||
(if (eq 'ein:cell-input-area (overlay-get ol 'face))
|
||||
(move-overlay (copy-overlay ol)
|
||||
(overlay-start ol) (overlay-end ol)
|
||||
dest-buf)))
|
||||
(with-current-buffer src-buf (overlays-in (point-min) (point-max))))
|
||||
(pm--move-vars (append ein:local-variables '(header-line-format buffer-undo-list))
|
||||
src-buf dest-buf)))
|
||||
|
||||
(defsubst poly-ein--set-buffer (src-buf dest-buf &optional switch)
|
||||
(when (and (not (eq src-buf dest-buf))
|
||||
(buffer-live-p src-buf)
|
||||
(buffer-live-p dest-buf))
|
||||
(cl-destructuring-bind (point window-start region-begin pos-visible _)
|
||||
(with-current-buffer src-buf (list (point) (window-start)
|
||||
(and switch (region-active-p) (mark))
|
||||
(pos-visible-in-window-p)
|
||||
(when switch (deactivate-mark))))
|
||||
(poly-ein-copy-state src-buf dest-buf)
|
||||
(if switch
|
||||
(switch-to-buffer dest-buf)
|
||||
(set-buffer dest-buf))
|
||||
(when region-begin
|
||||
(setq deactivate-mark nil) ;; someone is setting this, I don't know who
|
||||
(push-mark region-begin t t))
|
||||
(goto-char point)
|
||||
(setq syntax-propertize--done (point-min))
|
||||
(when switch
|
||||
(when pos-visible
|
||||
(set-window-start (get-buffer-window) window-start))
|
||||
(bury-buffer-internal src-buf)
|
||||
(set-window-prev-buffers
|
||||
nil
|
||||
(assq-delete-all src-buf (window-prev-buffers nil)))
|
||||
(run-hook-with-args 'polymode-switch-buffer-hook src-buf dest-buf)
|
||||
(pm--run-hooks pm/polymode :switch-buffer-functions src-buf dest-buf)
|
||||
(pm--run-hooks pm/chunkmode :switch-buffer-functions src-buf dest-buf)))))
|
||||
|
||||
(add-function
|
||||
:before-until (symbol-function 'pm-select-buffer)
|
||||
(lambda (span &optional visibly)
|
||||
(prog1 poly-ein-mode
|
||||
(when poly-ein-mode
|
||||
(let ((src-buf (current-buffer))
|
||||
(dest-buf (pm-span-buffer span)))
|
||||
;; (font-lock-flush)
|
||||
(poly-ein--set-buffer src-buf dest-buf visibly))))))
|
||||
|
||||
(add-function
|
||||
:override (symbol-function 'poly-lock-mode)
|
||||
(symbol-function (default-value 'font-lock-function)))
|
||||
|
||||
(defun poly-ein--narrow-to-inner (modifier f &rest args)
|
||||
(if (or pm-initialization-in-progress (not poly-ein-mode))
|
||||
(apply f args)
|
||||
(save-restriction
|
||||
(widen)
|
||||
(let ((range (pm-innermost-range
|
||||
(or (when (car args) (funcall modifier (car args)))
|
||||
(point)))))
|
||||
(narrow-to-region (car range) (cdr range))
|
||||
(apply f args)))))
|
||||
|
||||
(add-function
|
||||
:before-until (symbol-function 'syntax-propertize)
|
||||
(lambda (pos)
|
||||
(prog1 poly-ein-mode
|
||||
(when (and poly-ein-mode (< syntax-propertize--done pos))
|
||||
(save-excursion
|
||||
(with-silent-modifications
|
||||
(let ((parse-sexp-lookup-properties t)
|
||||
(start (point-min))
|
||||
(end (point-max)))
|
||||
;; (dolist (fun syntax-propertize-extend-region-functions)
|
||||
;; (ein:and-let* ((new (funcall fun start end)))
|
||||
;; (setq start (min start (car new)))
|
||||
;; (setq end (max end (cdr new)))))
|
||||
(setq syntax-propertize--done end)
|
||||
(remove-text-properties start end
|
||||
'(syntax-table nil syntax-multiline nil))
|
||||
;; avoid recursion if syntax-propertize-function calls me (syntax-propertize)
|
||||
(when syntax-propertize-function
|
||||
(let ((syntax-propertize--done most-positive-fixnum))
|
||||
(funcall syntax-propertize-function start end))))))))))
|
||||
|
||||
(add-function
|
||||
:around (symbol-function 'syntax-propertize)
|
||||
(apply-partially #'poly-ein--narrow-to-inner #'1-))
|
||||
|
||||
(add-function
|
||||
:around (symbol-function 'syntax-ppss)
|
||||
(apply-partially #'poly-ein--narrow-to-inner #'1-))
|
||||
|
||||
(add-function
|
||||
:around (symbol-function 'jit-lock-mode)
|
||||
(lambda (f &rest args)
|
||||
(cl-letf (((symbol-function 'buffer-base-buffer) #'ignore)) (apply f args))))
|
||||
|
||||
(defsubst poly-ein--span-start-end (args)
|
||||
(if (or pm-initialization-in-progress (not poly-ein-mode))
|
||||
args
|
||||
(let* ((span-start (first args))
|
||||
(span-end (second args))
|
||||
(range (pm-innermost-range (or span-start (point)))))
|
||||
(setq span-start (max (or span-start (car range)) (car range)))
|
||||
(setq span-end (min (or span-end (cdr range)) (cdr range)))
|
||||
(append (list span-start span-end) (cddr args)))))
|
||||
|
||||
(defsubst poly-ein--unrelated-span (&optional beg end)
|
||||
(or pm-initialization-in-progress
|
||||
(and poly-ein-mode
|
||||
(not (eq major-mode
|
||||
(eieio-oref (nth 3 (pm-innermost-span (or beg (point)))) :mode))))))
|
||||
|
||||
;; :before-until before :filter-args (reversed order when executed)
|
||||
|
||||
(add-function :before-until (symbol-function 'jit-lock-refontify)
|
||||
#'poly-ein--unrelated-span)
|
||||
|
||||
(add-function :before-until (symbol-function 'jit-lock-fontify-now)
|
||||
#'poly-ein--unrelated-span)
|
||||
|
||||
(add-function :filter-args (symbol-function 'jit-lock-refontify)
|
||||
#'poly-ein--span-start-end)
|
||||
|
||||
(add-function :filter-args (symbol-function 'jit-lock-fontify-now)
|
||||
#'poly-ein--span-start-end)
|
||||
|
||||
(add-function :filter-args (symbol-function 'font-lock-flush)
|
||||
#'poly-ein--span-start-end)
|
||||
|
||||
(add-function :filter-args (symbol-function 'jit-lock-after-change)
|
||||
#'poly-ein--span-start-end)
|
||||
|
||||
(make-variable-buffer-local 'parse-sexp-lookup-properties)
|
||||
(with-eval-after-load "markdown-mode"
|
||||
(fset 'markdown-unfontify-region-wiki-links #'ignore))
|
||||
|
||||
(add-function :before-until
|
||||
(symbol-function 'pm--synchronize-points)
|
||||
(lambda (&rest args) poly-ein-mode))
|
||||
|
||||
(provide 'poly-ein)
|
|
@ -51,7 +51,10 @@
|
|||
(ein:events-new))
|
||||
; matryoshka: new-content makes a ein:$content using CONTENT as template
|
||||
; populating its raw_content field with DATA's content field
|
||||
(ein:notebook-open--callback notebook nil nil (ein:new-content (ein:$notebook-url-or-port notebook) (ein:$notebook-notebook-path notebook) data))
|
||||
(ein:notebook-open--callback
|
||||
notebook nil nil
|
||||
(ein:new-content (ein:$notebook-url-or-port notebook)
|
||||
(ein:$notebook-notebook-path notebook) data))
|
||||
(ein:notebook-buffer notebook)))))
|
||||
|
||||
(defun ein:testing-notebook-make-data (name path cells)
|
||||
|
|
|
@ -3,27 +3,6 @@
|
|||
|
||||
(require 'ein-core)
|
||||
|
||||
|
||||
|
||||
;;; `ein:version'
|
||||
|
||||
(ert-deftest ein:version ()
|
||||
"Check if `ein:version' can be parsed by `version-to-list'."
|
||||
(version-to-list ein:version))
|
||||
|
||||
(ert-deftest ein:version-func-prefix-is-the-variable ()
|
||||
(should (string-prefix-p ein:version (ein:version)))
|
||||
(let ((default-directory "/tmp/"))
|
||||
(should (string-prefix-p ein:version (ein:version)))))
|
||||
|
||||
(ert-deftest ein:version-func-outside-of-git-repo ()
|
||||
(flet ((ein:git-root-p (dir) nil))
|
||||
(should (equal (ein:version) ein:version)))
|
||||
(flet ((ein:git-revision-dirty () nil))
|
||||
(should (equal (ein:version) ein:version))))
|
||||
|
||||
|
||||
|
||||
;; Generic getter
|
||||
|
||||
(defmacro eintest:generic-getter-should-return-nil (func)
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
(map-keymap assert-fboundp value))
|
||||
((and (listp value) (eq (car value) 'menu-item))
|
||||
(funcall assert-fboundp (cadr value) (caddr value)))
|
||||
((consp value)
|
||||
(should (functionp (cdr value))))
|
||||
(value ; nil is also valid in keymap
|
||||
(should (commandp value))))))
|
||||
(map-keymap assert-fboundp keymap)))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
(eval-when-compile (require 'cl))
|
||||
(require 'ert)
|
||||
|
||||
(require 'ein) ; for `ein:version'
|
||||
(require 'ein)
|
||||
(require 'ein-utils)
|
||||
|
||||
(ert-deftest ein-url-simple ()
|
||||
|
|
|
@ -186,18 +186,19 @@ See the definition of `create-image' for how it works."
|
|||
(should (search-forward-regexp "^Hello$" nil t))))))
|
||||
|
||||
(ert-deftest 14-notebook-execute-current-cell-question ()
|
||||
:expected-result (if (eq system-type 'darwin) t :passed)
|
||||
(let ((notebook (ein:testing-get-untitled0-or-create *ein:testing-port*)))
|
||||
(lexical-let ((notebook (ein:testing-get-untitled0-or-create *ein:testing-port*)))
|
||||
(ein:testing-wait-until
|
||||
(lambda () (ein:aand (ein:$notebook-kernel notebook)
|
||||
(ein:kernel-live-p it))))
|
||||
(with-current-buffer (ein:notebook-buffer notebook)
|
||||
(call-interactively #'ein:worksheet-insert-cell-below)
|
||||
(insert "range?")
|
||||
(let ((cell (call-interactively #'ein:worksheet-execute-cell)))
|
||||
(ein:testing-wait-until (lambda () (and (not (oref cell :running))
|
||||
(ein:$notebook-pager notebook)
|
||||
(get-buffer (ein:$notebook-pager notebook))))))
|
||||
(lexical-let ((cell (call-interactively #'ein:worksheet-execute-cell)))
|
||||
(ein:testing-wait-until
|
||||
(lambda ()
|
||||
(and (not (oref cell :running))
|
||||
(ein:$notebook-pager notebook)
|
||||
(get-buffer (ein:$notebook-pager notebook))))))
|
||||
(with-current-buffer (get-buffer (ein:$notebook-pager notebook))
|
||||
(should (search-forward "Docstring:"))))))
|
||||
|
||||
|
|
1
test/test-poly.el
Normal file
1
test/test-poly.el
Normal file
|
@ -0,0 +1 @@
|
|||
(setq ein:polymode t)
|
|
@ -19,6 +19,8 @@
|
|||
(setq ein:testing-dump-file-messages (concat default-directory "log/testfunc.messages"))
|
||||
(setq ein:testing-dump-file-server (concat default-directory "log/testfunc.server"))
|
||||
(setq ein:testing-dump-file-request (concat default-directory "log/testfunc.request"))
|
||||
(with-eval-after-load "python"
|
||||
(setq python-indent-guess-indent-offset-verbose nil))
|
||||
(ein:dev-start-debug)
|
||||
(ein:jupyter-server-start *ein:testing-jupyter-server-command* *ein:testing-jupyter-server-directory*)
|
||||
(ein:testing-wait-until (lambda () (ein:notebooklist-list)) nil 15000 1000)
|
||||
|
|
|
@ -4,7 +4,10 @@
|
|||
|
||||
# Define sample multi-line literal.
|
||||
input=`cat`
|
||||
replace=$(awk '/key.*binding/,EOF { print " " $0 }' <<<"$input")
|
||||
replace="$input"
|
||||
if [ ! -z "$3" ]; then
|
||||
replace=$(awk "/$3/,EOF { print \" \" \$0 }" <<<"$input")
|
||||
fi
|
||||
|
||||
# Escape it for use as a Sed replacement string.
|
||||
IFS= read -d '' -r < <(sed -e ':a' -e '$!{N;ba' -e '}' -e 's/[&/\]/\\&/g; s/\n/\\&/g' <<<"$replace")
|
||||
|
|
Loading…
Add table
Reference in a new issue