Commit graph

356 commits

Author SHA1 Message Date
Kevin Foley
8fdc3ae95b Preserve content in current cell when set to echo eval (#188)
* Preserve content in current cell when set to echo eval
2019-10-17 10:37:13 -05:00
Nathaniel Nicandro
91957986e1 Evaluation overlays
* README.org: Add section on `jupyter-eval-use-overlays`, minor formatting fix

* jupyter-client.el (jupyter-eval-overlay): New face.
(jupyter-eval-use-overlays, jupyter-eval-overlay-prefix): New custom variables.
(jupyter--display-eval-result): Remove function.
(jupyter-eval): Use `jupyter-eval-string`.
(jupyter-eval-result-callbacks): New function.
(jupyter-eval-add-callbacks): Result callbacks now obtained from
`jupyter-eval-result-callbacks`, only add callbacks for non-result message
types. Allow `beg` and `end` arguments remove `result-cb` argument, update all
callers.
(jupyter-eval-string): Allow `beg` and `end` arguments remove `cb` argument,
update all callers.
(jupyter-eval-string-command): Remove `cb` argument, update all callers.
(jupyter-eval-region): Ditto.
(jupyter-eval-line-or-region): Refactor.
(jupyter-eval-overlay-keymap): New keymap.
(jupyter-eval-ov--delete, jupyter-eval-ov--remove-all)
(jupyter-eval-ov--propertize, jupyter-eval-ov--fold-boundary)
(jupyter-eval-ov--expand-string, jupyter-eval-ov--make)
(jupyter-eval-ov--expand, jupyter-eval-ov--fold)
(jupyter-eval-toggle-overlay, jupyter-eval-remove-overlays)
(jupyter-eval-display-overlay, jupyter-eval-display-with-overlay-p): New
functions.

* jupyter-repl.el (jupyter-eval-string): Ensure callbacks are added in the
original (non-REPL) buffer the command was called from. So that
`jupyter-eval-display-with-overlay-p`, indirectly called by
`jupyter-eval-add-callbacks`, works.
(jupyter-repl-interaction-mode-map): Set `C-c C-o` binding to
`jupyter-eval-remove-overlays`.
2019-08-24 21:28:58 -05:00
Nathaniel Nicandro
39974d1841 jupyter-repl-restart-kernel: Use a kernel manager to restart if possible
* jupyter-repl.el (jupyter-repl-restart-kernel):
Call the `jupyter-shutdown-kernel` method of the client's kernel manager if
available.
Remove code that started a kernel when restarting if a manager was available,
this is already handled by `jupyter-shutdown-kernel`.
2019-08-08 22:04:27 -05:00
Nathaniel Nicandro
7a1c91eef4 Add the jupyter-kernel-process-manager class
So as to further generalize and separate out the abstract kernel manager class
from its various implementations.

* jupyter-kernel-manager.el (jupyter-meta-kernel): Fix documentation.
(jupyter-kernel-process, jupyter-command-kernel, jupyter-spec-kernel):
Move related functions and methods to `jupyter-kernel-process-manager.el`
(jupyter-kernel-manager-base): Remove class.
(jupyter-kernel-manager): Re-purpose class as the base class of all kernel
managers. The class corresponding to the old functionality is now named
`jupyter-kernel-process-manager`. Move all related functions and methods for
`jupyter-kernel-process-manager` to `jupyter-kernel-process-manager.el`.

* jupyter-kernel-process-manager.el: New file.

* jupyter-repl.el: Require `jupyter-kernel-process-manager` instead of
`jupyter-kernel-manager`.

* jupyter-server.el (jupyter-server-kernel-manager): Inherit from
`jupyter-kernel-manager` instead of `jupyter-kernel-manager-base`.

* test/jupyter-test.el (jupyter-kernel-lifetime)
(jupyter-command-kernel): Use `jupyter-kernel-process-manager` instead of
`jupyter-kernel-manager`.

* test/test-helper.el: Require `jupyter-kernel-process-manager` instead of
`jupyter-kernel-manager`.
2019-08-08 22:04:27 -05:00
Nathaniel Nicandro
23f41cf86c Add jupyter-kernel-alive-p method for a jupyter-kernel-client
* jupyter-client.el (jupyter-kernel-alive-p): Do it.

* jupyter-repl.el (jupyter-repl-connected-p): Use it.
2019-08-08 21:55:22 -05:00
Nathaniel Nicandro
8c711dd3ce jupyter-repl-client-has-manager-p -> jupyter-client-has-manager-p
* jupyter-client.el (jupyter-client-has-manager-p): New function.

* jupyter-repl.el (jupyter-repl-client-has-manager-p): Remove function.
(jupyter-repl-connected-p, jupyter-repl-kill-buffer-query-function):
(jupyter-repl-restart-kernel, jupyter-repl-display-kernel-buffer):
Rename calls to `jupyter-repl-client-has-manager-p` to
`jupyter-client-has-manager-p`.

* test/jupyter-test.el (jupyter-repl-client-predicates):
Rename calls to `jupyter-repl-client-has-manager-p` to
`jupyter-client-has-manager-p`.
2019-08-08 21:55:22 -05:00
Nathaniel Nicandro
3beb736853 Add jupyter-repl-completing-read-repl-buffer
* jupyter-repl.el (jupyter-repl-completing-read-repl-buffer): Do it.
(jupyter-repl-restart-kernel, jupyter-repl-associate-buffer): Use it.
2019-08-08 18:22:59 -05:00
Nathaniel Nicandro
6650dd3588 Bump version 2019-07-24 16:03:22 -05:00
Nathaniel Nicandro
e0531d040c jupyter-repl-ret: Suppress all handlers except :is-complete-reply
Fixes #153.
2019-07-24 14:59:47 -05:00
Nathaniel Nicandro
1e9da5753d Add jupyter-org-interrupt-kernel
* jupyter-org-extensions.el (jupyter-org-interrupt-kernel): Do it.
(jupyter-org-hydra/body): Add i binding.

* jupyter-repl.el (jupyter-repl-interrupt-kernel): Clarify error message.
2019-07-14 17:20:18 -05:00
Nathaniel Nicandro
8fc5f0bbee Make jupyter-channel-ioloop independent of zmq
This change localizes all `zmq` related functionality to `jupyter-ioloop` and
`jupyter-zmq-*` files.

* jupyter-channel-ioloop-comm.el: Add better commentary.
(jupyter-base): Require.
(jupyter-channel-ioloop-comm): Add `ioloop-class` slot
(initialize-instance [jupyter-channel-ioloop-comm]): Use it.

* jupyter-channel-ioloop.el (jupyter-base, jupyter-zmq-channel): Un-require.
(jupyter-ioloop-session, jupyter-ioloop-channels):
Rename to `jupyter-channel-ioloop-session` `jupyter-channel-ioloop-channels` and
update all callers.
(jupyter-channel-ioloop): Make into an abstract class.
(initialize-instance [jupyter-channel-ioloop]): Re-add
`jupyter-channel-ioloop-add-send-event`. Don't add to
`jupyter-ioloop-post-hook`.
(jupyter-channel-ioloop-recv-messages): Remove.
(jupyter-channel-ioloop--set-session, jupyter-ioloop-start)
(jupyter-channel-ioloop-add-send-event): Doc changes.
(jupyter-channel-ioloop-add-start-channel-event)
(jupyter-channel-ioloop-add-stop-channel-event):
Don't add/remove from the `jupyter-ioloop-poller`.
Now expected to be handled in the `jupyter-channel` subclass.
Update documentation. In addition, for the start-channel event,
do not attempt to add a channel if one doesn't already exist.

* jupyter-ioloop.el
(jupyter-ioloop-add-teardown):
Remove mention of `jupyter-channel-ioloop` behavior.
(jupyter-ioloop-add-arg-type): Update example variable.
(jupyter-ioloop-environment-p): New function.

* jupyter-kernel-manager.el (jupyter-channel): Require.
(jupyter-make-client): Require and use `jupyter-zmq-channel-ioloop`.
(jupyter-start-channels): Use `make-instance`.
(jupyter-interrupt-kernel): Remove `condition-case`. Not needed since
preventing socket blocking is now handled by `jupyter-recv`.

* jupyter-repl.el
(jupyter-connect-repl): Require and use `jupyter-zmq-channel-ioloop`.

* jupyter-zmq-channel-ioloop.el: New file.

* jupyter-zmq-channel.el (jupyter-ioloop-poller-remove)
(jupyter-ioloop-poller-add): New declares.
(jupyter-start-channel):
Add to `jupyter-ioloop-poller` when in `jupyter-ioloop-environment-p`.
(jupyter-stop-channel):
Only disconnect the socket from its endpoint instead of closing it, leave that
up to garbage collection.
Remove from `jupyter-ioloop-poller` when in `jupyter-ioloop-environment-p`.
(jupyter-recv): Handle non-blocking.

* test/jupyter-test.el
(jupyter-zmq-channel): Use non-blocking `zmq-send` since socket is no longer
closed when calling `jupyter-stop-channel`.
(jupyter-ioloop-test-eval-ioloop): Rename to `jupyter-test-ioloop-eval-event`,
update all callers, and move to `test/test-helper.el`.
(jupyter-channel-ioloop-send-event, jupyter-channel-ioloop-stop-channel-event)
(jupyter-channel-ioloop-start-channel-event): Fix tests for variable name
changes. Use `jupyter-test-channel-ioloop`. Update `jupyter-ioloop-poller`,
addition/removal from poller is now done in the `jupyter-channel` subclass by
checking `jupyter-ioloop-environment-p`.

* test/test-helper.el (jupyter-zmq-channel-ioloop): Require.
(initialize-instance [jupyter-echo-client]): Use it.
(jupyter-test-channel-ioloop): New macro.
(jupyter-test-ioloop-eval-event): New function.
2019-06-30 12:22:26 -05:00
Nathaniel Nicandro
b40b7de837 Do not depend strongly on zmq
Having the `jupyter-comm-layer` abstraction means we do not need to do so.

* jupyter-base.el (zmq): Un-require.
(jupyter-socket-types): Move to `jupyter-channels.el`.
(jupyter-session): Don't mention zmq in doc string.
(jupyter-available-local-ports, jupyter-make-ssh-tunnel): New functions.
(jupyter-tunnel-connection): Use them.

* jupyter-channel-ioloop-comm.el: New file.

* jupyter-channels.el (jupyter-messages): Un-require.
(jupyter-comm-layer, zmq): New requires.
(jupyter-socket-types): Moved from `jupyter-base.el`.
(jupyter-send, jupyter-recv):
Implementations for `jupyter-session` moved from `jupyter-messages.el`.
(jupyter-sync-channel-comm): `jupyter-comm-layer` implementation for
`jupyter-sync-channel` objects moved from `jupyter-comm-layer.el`.

* jupyter-comm-layer.el (jupyter-channel-ioloop): Un-require.
(jupyter-sync-channel-comm): Move implementation to `jupyter-channels.el`.
(jupyter-ioloop-comm): Move implementation to new file `jupyter-ioloop-comm.el`.
(jupyter-channel-ioloop-comm):
Move implementation to new file `jupyter-channel-ioloop-comm.el`.

* jupyter-ioloop-comm.el: New file.

* jupyter-ioloop.el (zmq): Require.

* jupyter-kernel-manager.el
(jupyter-make-client): Ensure `jupyter-channel-ioloop-comm` is required.

* jupyter-messages.el (jupyter-send)
(jupyter-recv): Moved to `jupyter-channels.el`

* jupyter-repl.el
(jupyter-connect-repl): Ensure `jupyter-channel-ioloop-comm` is required.

* test/jupyter-test.el (jupyter-available-local-ports): New test.

* test/test-helper.el (jupyter-channel-ioloop-comm): New require.
2019-06-29 10:29:55 -05:00
Nathaniel Nicandro
9dd8e8d9ec Localize functions defined in jupyter-base.el to their call sites
Fixes #137

* jupyter-base.el (jupyter-kernelspec): Un-require.
(jupyter-command, jupyter-locate-python)
(jupyter-runtime-directory): Move to new file `jupyter-env.el`
(jupyter-include-other-output, jupyter-iopub-message-hook)
(jupyter-shell-message-hook)
(jupyter-stdin-message-hook): Move to `jupyter-client.el`
(jupyter-sha256, jupyter-hmac-sha256):
(jupytern-new-uuid): Move to `jupyter-messages.el`. Add declaration of
`jupyter-new-uuid` to account for its removal.
(jupyter-create-connection-info)
(jupyter-write-connection-file): Move to `jupyter-kernel-manager.el`
(jupyter-connect-endpoint, jupyter-connect-channel): Move to `jupyter-channels.el`

* jupyter-channels.el: Accept moved functions.

* jupyter-client.el: Accept moved variables.

* jupyter-kernel-manager.el: Accept moved functions.
(jupyter-env, jupyter-kernelspec): New requires.

* jupyter-kernelspec (jupyter-env): New require.
(jupyter-command): Remove declaration.
(jupyter-read-plist-from-string): New declaration.

* jupyter-messages.el: Accept moved functions.
(hmac-def, json): New requires.

* jupyter-org-extensions.el (jupyter-kernelspec): New require.

* jupyter-repl.el (jupyter-kernelspec): New require.

* jupyter-env.el: New file.

* ob-jupyter.el (jupyter-env, jupyter-kernelspec): New requires.

* test/jupyter-test.el (jupyter-env): New require.
2019-06-29 10:29:55 -05:00
Nathaniel Nicandro
030c3e2d0c Fix issues with undo in the REPL
Related to let binding `buffer-undo-list` improperly and making text read-only
when it shouldn't be.

Fixes #139

* jupyter-repl.el (jupyter-repl-with-single-undo)
(jupyter-repl-inhibit-undo-when): New macros.
(jupyter-repl-insert): Inhibit undo only when insertions are `read-only`
(jupyter-repl-insert-prompt): Don't make continuation prompts `read-only`
(jupyter-repl-replace-cell-code): Allow the argument to be a `buffer`. Use
`replace-buffer-contents` in this case. Avoids unnecessary undo information.
(jupyter-handle-is-complete-reply): Don't insert a `read-only` newline on
incomplete cell code.
(jupyter-repl-indent-line): Pass buffer to `jupyter-repl-replace-cell-code`
(jupyter-repl-insert-continuation-prompts): Don't inhibit undo

* test/jupyter-test.el (jupyter-repl-undo): Add more tests.
2019-06-29 10:29:55 -05:00
Nathaniel Nicandro
95b985e8d6 jupyter-repl-clear-cells: Move to cell code beginning 2019-06-28 20:13:24 -05:00
Nathaniel Nicandro
a4d95aab80 jupyter-handle-message: Drop idle messages less frequently
This accounts for idle messages being dropped before a request's reply message.
In such a case, the request is dropped from the client's request table before
the handlers/callbacks of the request get a chance to handle the reply message.
2019-06-25 09:58:14 -05:00
Nathaniel Nicandro
44c3c1a9ea Add jupyter-comm-id
Used to get an identification string of the connection that a kernel client is
using.
2019-06-22 21:57:00 -05:00
Nathaniel Nicandro
1913da83fa org-babel-jupyter-scratch-buffer: Don't switch buffers when inside edit buffer 2019-06-12 23:22:20 -05:00
Nathaniel Nicandro
40ee1ac8b9 Add new customizable variable jupyter-repl-echo-eval-p
Closes #71
2019-06-08 13:47:13 -05:00
Nathaniel Nicandro
6289e23c61 Turn jupyter-eval-string into a method
So that client subclasses can provide specialized behavior if needed.

Also adds the function `jupyter-eval-add-callbacks` so that client methods can
more easily obtain the default behavior of `jupyter-eval-string'.
2019-06-08 13:47:13 -05:00
Nathaniel Nicandro
4b04834712 Add jupyter-repl-clear-cells 2019-06-01 12:27:30 -05:00
Nathaniel Nicandro
5ea32a70f0 Change License to GPL3 2019-05-31 09:44:39 -05:00
Nathaniel Nicandro
49275c37b8 jupyter-repl-mode: Be more consistent when getting REPL history 2019-05-30 23:02:40 -05:00
Nathaniel Nicandro
7e64dd9f9c jupyter-error-if-not-client-class-p: Allow a class to check against 2019-05-23 08:49:41 -05:00
Nathaniel Nicandro
f161c7dfac Add new method jupyter-bootstrap-repl 2019-05-23 08:39:38 -05:00
Nathaniel Nicandro
7554293d18 Add bindings for jupyter-repl-history-(previous|next)-matching
These are the same bindings as found in `comint-mode`
2019-05-19 19:39:11 -05:00
Nathaniel Nicandro
d7757d6de4 jupyter-repl-history--rotate: Handle an empty history 2019-05-19 19:34:07 -05:00
poppyschmo
b7b0162572 Add prev/next-matching REPL-input-history commands (#108) 2019-05-19 19:13:14 -05:00
Nathaniel Nicandro
107fa8042d Generalize jupyter-repl-history navigation functions 2019-05-18 20:35:28 -05:00
Nathaniel Nicandro
d7ce2b0c38 jupyter-repl-preserve-window-margins: Remove superfluous doc 2019-05-09 20:10:49 -05:00
Nathaniel Nicandro
b715ada492 Always name method arguments
If method arguments are not named it gives rise to errors like

    `Args out of range: "", 0`

that originate in `help-function-arglist` when calling `describe-function` on
those methods.
2019-05-09 13:32:45 -05:00
Nathaniel Nicandro
3628cab446 Refactor of jupyter-kernel-manager.el
This refactor implements a new class hierarchy to manage the lifetime of a
Jupyter kernel. The first node in this hierarchy is the
`jupyter-kernel-lifetime` class which defines a set of methods to manage the
lifetime of a kernel. An object that inherits from `jupyter-kernel-lifetime` is
stating that it has an association with a kernel and can be used to manage the
lifetime of the associated kernel.

The `jupyter-meta-kernel` class inherits from `jupyter-kernel-lifetime` and
mainly defines a `spec` slot used to hold the `kernelspec` from which a command
can be constructed to start a kernel and a `session` slot used to hold the
`jupyter-session` object that clients can use to establish communication with a
kernel once its live. Concrete classes that actually launch kernels are
intended to inherit from this class and use its slots.

`jupyter-kernel-process` manages the lifetime of a kernel started as a process
using the function `start-file-process`, `jupyter-command-kernel` calls the
`jupyter kernel` shell command to start a kernel, finally `jupyter-spec-kernel`
uses the `spec` slot to construct a shell command to start a kernel.

A `jupyter-kernel-manager` now consists of a `kernel` slot that holds a
`jupyter-meta-kernel` and a `control-channel` slot and inherits from
`jupyter-kernel-lifetime`. The `jupyter-kernel-lifetime` methods of the manager
just defer to those of `kernel` while also taking into account the
`control-channel`.

* jupyter-base.el (jupyter-write-connection-file): New function.

* jupyter-channel-ioloop.el
(jupyter-channel-ioloop-add-start-channel-event): Remove `sleep-for` call.
The startup message is not so important anymore.

* jupyter-client.el (jupyter-wait-until-startup: New function.

* jupyter-kernel-manager.el (jupyter-kernel-lifetime)
(jupyter-kernel, jupyter-kernel-process, jupyter-command-kernel)
(jupyter-spec-kernel): New classes.
(jupyter-kernel-manager): Inherit from jupyter-kernel-lifetime only and
implement its methods.
(jupyter-kernel-manager--cleanup, jupyter-kernel-managers)
(jupyter-delete-all-kernels, jupyter--kernel-sentinel)
(jupyter--start-kernel): Remove and remove related, their functionality has
been generalized in the new classes.
(jupyter-interrupt-kernel, jupyter-shutdown-kernel)
(jupyter-start-channels, jupyter-start-kernel, jupyter-kernel-alive-p)
(jupyter-kill-kernel): Refactor and implement to use the new class hierarchy.

* test/jupyter-test.el: Refactor tests to account for changes.
(jupyter-write-connect-file, jupyter-command-kernel): New tests.

* jupyter-kernelspec.el (jupyter-guess-kernelspec): New function.
2019-05-09 12:20:27 -05:00
Nathaniel Nicandro
112769e0c6
Bump version 2019-05-04 03:31:50 -05:00
Nathaniel Nicandro
9d685b0be4
jupyter-repl-mode-map: Don't override default point motion keys
Closes #100
2019-04-25 12:04:41 -05:00
Nathaniel Nicandro
9d39fbeaff
jupyter-connect-repl: Set kcomm slot of client before initializing connection
Fixes #92
2019-04-15 21:39:55 -05:00
Nathaniel Nicandro
8926e90f37
jupyter-handle-is-complete-reply (jupyter-repl-client): Handle unknown status 2019-04-12 17:06:14 -05:00
Nathaniel Nicandro
34a4833fdd
Add jupyter-repl-allow-RET-when-busy
Closes #82
2019-04-12 11:09:29 -05:00
jackkamm
e7de8b31af Integration for R (#89) 2019-04-12 08:56:20 -05:00
Nathaniel Nicandro
49571ecd8d
jupyter-repl-display-kernel-buffer: Ensure that the manager has a kernel process 2019-04-08 12:44:49 -05:00
Daniel Gomez
96c872fb7c Set show-trailing-whitespace to nil for jupyter buffers. (#83) 2019-04-06 12:39:00 -05:00
Nathaniel Nicandro
82ec2fb786 Handle all valid arguments in client propagating advise
Fixes #76.
2019-04-01 21:45:00 -05:00
Nathaniel Nicandro
25975b9fae
Use the right type predicates 2019-03-25 13:19:02 -05:00
Nathaniel Nicandro
2f18192ae7
Remove redundant :execute-input handlers
The `execution-count` slot of a `jupyter-kernel-client` is now updated higher
up in the message handling process which makes these handlers unnecessary.
2019-03-25 13:19:02 -05:00
Nathaniel Nicandro
569ae50214
jupyter-repl-ret: Avoid syncing execution state
There is really no reason for this sync since it happens after checking if the
kernel is busy and the execution-count is now updated whenever an execute_input
message is received in the `jupyter-handle-message` of a
`jupyter-kernel-client`.
2019-03-24 00:11:22 -05:00
Nathaniel Nicandro
0e8e10babb
jupyter-repl-initialize-fontification: Protect against nil font-lock-defaults 2019-03-20 21:05:46 -05:00
Nathaniel Nicandro
c010d83696
jupyter-repl-initialize-fontification: Don't fail if functions aren't present 2019-03-17 20:31:25 -05:00
Nathaniel Nicandro
83af335166
Bump version 2019-03-14 09:29:11 -05:00
Nathaniel Nicandro
662e983612
Don't require subr-x at runtime 2019-03-14 09:16:44 -05:00
Nathaniel Nicandro
4f8e5da4ba
Ensure the REPL buffer is current when inserting banner 2019-03-10 04:39:43 -05:00
Nathaniel Nicandro
49d43b690e
jupyter-repl.el: Update commentary 2019-03-10 03:06:16 -05:00