Skip to content

Commit 356e902

Browse files
committed
Add jupyter-repl-without-is-complete functionality
* README.org: Document the functionality. * jupyter-repl.el (jupyter-repl-without-is-complete): New custom variable. (jupyter-repl-send): New interactive function to send code immediately without using an is_complete_request so that no checking of the code syntax is done. (jupyter-repl-ret): Update behavior to take into account `jupyter-repl-without-is-complete` and get rid of the call to the spoofed call to `jupyter-handle-is-complete-reply`.
1 parent 42f2b1e commit 356e902

File tree

2 files changed

+77
-21
lines changed

2 files changed

+77
-21
lines changed

README.org

+15
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,21 @@ A variable that determines whether to allow insertion of newlines in a
232232
REPL cell when a kernel is busy or not. See the variable
233233
documentation for more details.
234234

235+
*** =jupyter-repl-without-is-complete=
236+
237+
A variable that determines whether or not an is_complete_request is
238+
sent to the kernel to determine the syntactical correctness, i.e. when
239+
it is safe to send it for evaluation. When it is non-nil, no
240+
is_complete_request is used and the main way to send code to kernels
241+
for evaluation is a press of =S-RET=, =RET= would insert a newline and
242+
indent in this case. When the variable is nil, =RET= sends an
243+
is_complete_request to determine if the code is valid to send for
244+
execution or not and sends it if it is or inserts a newline and
245+
indents if it isn't.
246+
247+
See also =jupyter-repl-use-builtin-is-complete= for another method of
248+
sending code to kernels without the use of an is_complete_request.
249+
235250
*** =jupyter-repl-echo-eval-p=
236251

237252
A variable that determines whether code evaluated with

jupyter-repl.el

+62-21
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,24 @@ send the code to the kernel."
143143
:type 'boolean
144144
:group 'jupyter-repl)
145145

146+
(defcustom jupyter-repl-without-is-complete nil
147+
"Whether or not is_complete_request handling is done.
148+
If this variable is nil, an is_complete_request is usually sent
149+
to the kernel on every press of
150+
\\<jupyter-repl-mode-map>\\[jupyter-repl-ret] to determine if the
151+
code is syntactically correct before sending it to be executed.
152+
If the kernel responds to this message by saying that the code is
153+
correct, then the code is sent to be executed immediately.
154+
155+
If this variable is non-nil,
156+
\\<jupyter-repl-mode-map>\\[jupyter-repl-ret] no longer sends
157+
is_complete_request messages nor does what is explained by
158+
`jupyter-repl-use-builtin-is-complete' and just inserts a newline
159+
and indents. In order to send an execute_request in this case,
160+
you have to press \\<jupyter-repl-mode-map>\\[jupyter-repl-send]."
161+
:type 'boolean
162+
:group 'jupyter-repl)
163+
146164
(defcustom jupyter-repl-echo-eval-p nil
147165
"Copy evaluation input to a REPL cell if non-nil.
148166
If non-nil, and when calling the `jupyter-eval-*' functions like
@@ -196,11 +214,18 @@ current output of the cell. Set when the kernel sends a
196214
"The history of the current Jupyter REPL.")
197215

198216
(defvar-local jupyter-repl-use-builtin-is-complete nil
199-
"Whether or not to send `:is-complete-request's to a kernel.
217+
"Whether or not to send an is_complete_request to a kernel.
200218
If a Jupyter kernel does not respond to an is_complete_request,
201219
the buffer local value of this variable is set to t and code in a
202220
cell is considered complete if the last line in a code cell is a
203-
blank line, i.e. if RET is pressed twice in a row.")
221+
blank line, i.e. if \\<jupyter-repl-mode-map>\\[jupyter-repl-ret]
222+
is pressed twice in a row.
223+
224+
Note `jupyter-repl-without-is-complete' takes precedence over
225+
this variable so when `jupyter-repl-without-is-complete' is
226+
non-nil you have to press
227+
\\<jupyter-repl-mode-map>\\[jupyter-repl-send] to send the code
228+
regardless of the setting of this variable..")
204229

205230
(cl-generic-define-context-rewriter jupyter-repl-mode (mode &rest modes)
206231
`(jupyter-repl-lang-mode (derived-mode ,mode ,@modes)))
@@ -1169,16 +1194,23 @@ elements."
11691194
(when restart
11701195
(jupyter-repl--insert-banner-and-prompt client))))))))
11711196

1197+
(defun jupyter-repl-send ()
1198+
"Send the current cell code to the kernel.
1199+
As opposed to `jupyter-repl-ret' this sends the code immediately
1200+
without considering the syntactical correctness of the code."
1201+
(interactive)
1202+
(jupyter-repl-ret 'force))
1203+
11721204
(defun jupyter-repl-ret (&optional force)
11731205
"Send the current cell code to the kernel.
11741206
If `point' is before the last cell in the REPL buffer move to
11751207
`point-max', i.e. move to the last cell. Otherwise if `point' is
11761208
at some position within the last cell, either insert a newline or
11771209
ask the kernel to execute the cell code depending on the kernel's
1178-
response to an `:is-complete-request'.
1210+
response to an is_complete_request.
11791211
11801212
If a prefix argument is given, FORCE the kernel to execute the
1181-
current cell code without sending an `:is-complete-request'. See
1213+
current cell code without sending an is_complete_request. See
11821214
`jupyter-repl-use-builtin-is-complete' for yet another way to
11831215
execute the current cell."
11841216
(interactive "P")
@@ -1190,27 +1222,33 @@ execute the current cell."
11901222
(goto-char (point-max))
11911223
(unless (jupyter-repl-connected-p)
11921224
(error "Kernel not alive"))
1193-
;; NOTE: kernels allow execution requests to queue up, but we prevent
1194-
;; sending a request when the kernel is busy because of the
1195-
;; is-complete request. Some kernels don't respond to this request
1196-
;; when the kernel is busy.
1197-
(when (and (jupyter-kernel-busy-p jupyter-current-client)
1198-
(not jupyter-repl-allow-RET-when-busy))
1199-
(error "Kernel busy"))
1225+
(unless (eq this-command 'jupyter-repl-send)
1226+
;; NOTE: kernels allow execution requests to queue up, but
1227+
;; we prevent sending a request when the kernel is busy
1228+
;; because of the is_complete_request. Some kernels don't
1229+
;; respond to this request when the kernel is busy.
1230+
(when (and (jupyter-kernel-busy-p jupyter-current-client)
1231+
(not jupyter-repl-allow-RET-when-busy))
1232+
(error "Kernel busy")))
12001233
(cond
12011234
(force (jupyter-repl-execute-cell))
1235+
(jupyter-repl-without-is-complete
1236+
(newline)
1237+
(jupyter-repl-indent-line))
12021238
((or jupyter-repl-use-builtin-is-complete
12031239
(and jupyter-repl-allow-RET-when-busy
12041240
(jupyter-kernel-busy-p jupyter-current-client)))
1205-
(goto-char (point-max))
1206-
(let ((complete-p (equal (buffer-substring-no-properties
1207-
(line-beginning-position) (point))
1208-
"")))
1209-
(jupyter-handle-is-complete-reply
1210-
jupyter-current-client
1211-
nil `(:content
1212-
(:status ,(if complete-p "complete" "incomplete")
1213-
:indent "")))))
1241+
(if (save-excursion
1242+
(goto-char (point-max))
1243+
(string-empty-p
1244+
(buffer-substring
1245+
(line-beginning-position)
1246+
(point))))
1247+
(let ((client jupyter-current-client))
1248+
(jupyter-run-soon
1249+
(jupyter-repl-execute-cell client)))
1250+
(newline)
1251+
(jupyter-repl-indent-line)))
12141252
(t
12151253
(condition-case nil
12161254
(jupyter-run-with-client jupyter-current-client
@@ -1221,7 +1259,7 @@ execute the current cell."
12211259
jupyter-repl-maximum-is-complete-timeout))
12221260
(jupyter-timeout-before-idle
12231261
(message "\
1224-
Kernel did not respond to is-complete-request, using built-in is-complete.
1262+
Kernel did not respond to is_complete_request, using built-in is_complete.
12251263
Reset `jupyter-repl-use-builtin-is-complete' to nil if this is only temporary.")
12261264
(setq jupyter-repl-use-builtin-is-complete t)
12271265
(jupyter-repl-ret force)))))))
@@ -1658,6 +1696,9 @@ Return the buffer switched to."
16581696
(define-key map [remap backward-sentence] #'jupyter-repl-backward-cell)
16591697
(define-key map [remap forward-sentence] #'jupyter-repl-forward-cell)
16601698
(define-key map (kbd "RET") #'jupyter-repl-ret)
1699+
(define-key map (kbd "S-RET") #'jupyter-repl-send)
1700+
(define-key map (kbd "<return>") #'jupyter-repl-ret)
1701+
(define-key map (kbd "S-<return>") #'jupyter-repl-send)
16611702
(define-key map (kbd "M-n") #'jupyter-repl-history-next)
16621703
(define-key map (kbd "M-p") #'jupyter-repl-history-previous)
16631704
(define-key map (kbd "C-c C-o") #'jupyter-repl-clear-cells)

0 commit comments

Comments
 (0)