mirror of
https://github.com/vale981/emacs-jupyter
synced 2025-03-05 07:41:37 -05:00
Replace jupyter-repl-cell-cond
with jupyter-repl-map-cells
* jupyter-repl.el (jupyter-repl-map-cells): New function. (jupyter-repl-cell-cond): Remove. Update callers with new function. * jupyter-julia.el: Ditto. * test/jupyter-test.el (jupyter-repl-map-cells): New test. (jupyter-repl-cell-cond): Remove.
This commit is contained in:
parent
25270f7d3b
commit
a9ae0bcef5
3 changed files with 65 additions and 76 deletions
|
@ -171,8 +171,8 @@ nil."
|
||||||
;;; REPL font lock
|
;;; REPL font lock
|
||||||
|
|
||||||
(defun jupyter-julia--propertize-repl-mode-char (beg end)
|
(defun jupyter-julia--propertize-repl-mode-char (beg end)
|
||||||
(jupyter-repl-cell-cond
|
(jupyter-repl-map-cells beg end
|
||||||
beg end
|
(lambda ()
|
||||||
;; Handle Julia package prompt so `syntax-ppss' works properly.
|
;; Handle Julia package prompt so `syntax-ppss' works properly.
|
||||||
(when (and (eq (char-syntax (char-after (point-min))) ?\))
|
(when (and (eq (char-syntax (char-after (point-min))) ?\))
|
||||||
(= (point-min)
|
(= (point-min)
|
||||||
|
@ -182,7 +182,8 @@ nil."
|
||||||
;; which is why the widen is needed here.
|
;; which is why the widen is needed here.
|
||||||
(jupyter-repl-cell-code-beginning-position))))
|
(jupyter-repl-cell-code-beginning-position))))
|
||||||
(put-text-property
|
(put-text-property
|
||||||
(point-min) (1+ (point-min)) 'syntax-table '(1 . ?.)))))
|
(point-min) (1+ (point-min)) 'syntax-table '(1 . ?.))))
|
||||||
|
#'ignore))
|
||||||
|
|
||||||
;;; `jupyter-repl-after-init'
|
;;; `jupyter-repl-after-init'
|
||||||
|
|
||||||
|
|
119
jupyter-repl.el
119
jupyter-repl.el
|
@ -264,42 +264,6 @@ The cell is narrowed to the region between and including
|
||||||
(jupyter-repl-cell-code-end-position))
|
(jupyter-repl-cell-code-end-position))
|
||||||
,@body)))
|
,@body)))
|
||||||
|
|
||||||
(defmacro jupyter-repl-cell-cond (beg end input-form &rest output-forms)
|
|
||||||
"Conditionally evaluate INPUT-FORM or OUTPUT-FORMS between BEG and END.
|
|
||||||
INPUT-FORM is evaluated for every input cell between BEG and END
|
|
||||||
with the buffer narrowed to the region of the input cell.
|
|
||||||
|
|
||||||
Similarly, OUTPUT-FORMS is evaluated for every output cell region
|
|
||||||
with the buffer narrowed to the output cell.
|
|
||||||
|
|
||||||
Note the narrowed regions may not be full input/output cells if
|
|
||||||
BEG and END are within an input/output cell."
|
|
||||||
(declare (indent 3) (debug ([&or symbolp form] [&or symbolp form]
|
|
||||||
form &rest form)))
|
|
||||||
(let ((start (make-symbol "start"))
|
|
||||||
(next (make-symbol "next"))
|
|
||||||
(-end (make-symbol "-end")))
|
|
||||||
`(save-excursion
|
|
||||||
(save-restriction
|
|
||||||
(let ((,start ,beg)
|
|
||||||
(,-end ,end)
|
|
||||||
,next)
|
|
||||||
(while (/= ,start ,-end)
|
|
||||||
(widen)
|
|
||||||
(cond
|
|
||||||
((eq (get-text-property ,start 'field) 'cell-code)
|
|
||||||
(setq ,next (min ,-end (field-end ,start t)))
|
|
||||||
(narrow-to-region ,start ,next)
|
|
||||||
,input-form)
|
|
||||||
(t
|
|
||||||
(setq ,next (or (text-property-any
|
|
||||||
,start ,-end 'field 'cell-code)
|
|
||||||
,-end))
|
|
||||||
,@(when output-forms
|
|
||||||
`((narrow-to-region ,start ,next)
|
|
||||||
,@output-forms))))
|
|
||||||
(setq ,start ,next)))))))
|
|
||||||
|
|
||||||
(defmacro jupyter-repl-inhibit-undo-when (cond &rest body)
|
(defmacro jupyter-repl-inhibit-undo-when (cond &rest body)
|
||||||
"Evaluate BODY, disabling undo beforehand if COND is non-nil.
|
"Evaluate BODY, disabling undo beforehand if COND is non-nil.
|
||||||
Undo is re-enabled after BODY is evaluated.
|
Undo is re-enabled after BODY is evaluated.
|
||||||
|
@ -670,6 +634,33 @@ ARG is the number of cells to move and defaults to 1."
|
||||||
(jupyter-repl-previous-cell arg)
|
(jupyter-repl-previous-cell arg)
|
||||||
(goto-char (jupyter-repl-cell-code-beginning-position)))
|
(goto-char (jupyter-repl-cell-code-beginning-position)))
|
||||||
|
|
||||||
|
(defun jupyter-repl-map-cells (beg end input output)
|
||||||
|
"Call INPUT or OUTPUT on the corresponding cells between BEG and END.
|
||||||
|
For every input or output cell between BEG and END, call INPUT or
|
||||||
|
OUTPUT, respectively, with the buffer narrowed to the cell.
|
||||||
|
INPUT and OUTPUT are functions of no arguments.
|
||||||
|
|
||||||
|
Note the narrowed regions may not be full input/output cells if
|
||||||
|
BEG and END are within an input/output cell."
|
||||||
|
(declare (indent 2))
|
||||||
|
(save-excursion
|
||||||
|
(save-restriction
|
||||||
|
(let (next)
|
||||||
|
(while (/= beg end)
|
||||||
|
(widen)
|
||||||
|
(cond
|
||||||
|
((eq (get-text-property beg 'field) 'cell-code)
|
||||||
|
(setq next (min end (field-end beg t)))
|
||||||
|
(narrow-to-region beg next)
|
||||||
|
(funcall input))
|
||||||
|
(t
|
||||||
|
(setq next (or (text-property-any
|
||||||
|
beg end 'field 'cell-code)
|
||||||
|
end))
|
||||||
|
(narrow-to-region beg next)
|
||||||
|
(funcall output)))
|
||||||
|
(setq beg next))))))
|
||||||
|
|
||||||
;;; Predicates
|
;;; Predicates
|
||||||
|
|
||||||
(defun jupyter-repl-cell-beginning-p (&optional pos)
|
(defun jupyter-repl-cell-beginning-p (&optional pos)
|
||||||
|
@ -1779,33 +1770,30 @@ would look like
|
||||||
"Use FONTIFY-FUN to fontify input cells between BEG and END.
|
"Use FONTIFY-FUN to fontify input cells between BEG and END.
|
||||||
VERBOSE has the same meaning as in
|
VERBOSE has the same meaning as in
|
||||||
`font-lock-fontify-region-function'."
|
`font-lock-fontify-region-function'."
|
||||||
(jupyter-repl-cell-cond
|
(jupyter-repl-map-cells beg end
|
||||||
beg end
|
;; Ensure that the buffer is narrowed to the actual cell code before calling
|
||||||
;; Ensure that the buffer is narrowed to the actual cell code before
|
;; the REPL language's `major-mode' specific fontification functions since
|
||||||
;; calling the REPL language's `major-mode' specific fontification
|
;; those functions don't know anything about input cells or output cells and
|
||||||
;; functions since those functions don't know anything about input cells
|
;; may traverse cell boundaries.
|
||||||
;; or output cells and may traverse cell boundaries.
|
;;
|
||||||
;;
|
;; It is OK that we do not update BEG and END using the return value of this
|
||||||
;;
|
;; function as long as the default value of
|
||||||
;; It is OK that we do not update BEG and END using the return value of
|
;; `font-lock-extend-region-functions' is used since an input cell always
|
||||||
;; this function as long as the default value of
|
;; starts at the beginning of a line and ends at the end of a line and does
|
||||||
;; `font-lock-extend-region-functions' is used since an input cell always
|
;; not use the font-lock-multiline property (2018-12-20).
|
||||||
;; starts at the beginning of a line and ends at the end of a line and
|
(lambda () (funcall fontify-fun (point-min) (point-max) verbose))
|
||||||
;; does not use the font-lock-multiline property (2018-12-20).
|
;; Unfontify the region mainly to remove the font-lock-multiline property in
|
||||||
(funcall fontify-fun (point-min) (point-max) verbose)
|
;; the output, e.g. added by markdown. These regions will get highlighted
|
||||||
;; Unfontify the region mainly to remove the font-lock-multiline property
|
;; syntactically in some scenarios.
|
||||||
;; in the output, e.g. added by markdown. These regions will get
|
(lambda () (font-lock-unfontify-region (point-min) (point-max))))
|
||||||
;; highlighted syntactically in some scenarios.
|
|
||||||
(font-lock-unfontify-region (point-min) (point-max)))
|
|
||||||
`(jit-lock-bounds ,beg . ,end))
|
`(jit-lock-bounds ,beg . ,end))
|
||||||
|
|
||||||
(defun jupyter-repl-syntax-propertize-function (propertize-fun beg end)
|
(defun jupyter-repl-syntax-propertize-function (propertize-fun beg end)
|
||||||
"Use PROPERTIZE-FUN to syntax propertize text between BEG and END."
|
"Use PROPERTIZE-FUN to syntax propertize text between BEG and END."
|
||||||
(jupyter-repl-cell-cond
|
(jupyter-repl-map-cells beg end
|
||||||
beg end
|
;; See note in `jupyter-repl-font-lock-fontify-region' on why the buffer
|
||||||
;; See note in `jupyter-repl-font-lock-fontify-region' on why the buffer
|
;; should be narrowed to the input cell before calling this function.
|
||||||
;; should be narrowed to the input cell before calling this function.
|
(lambda () (funcall propertize-fun (point-min) (point-max)))
|
||||||
(funcall propertize-fun (point-min) (point-max))
|
|
||||||
;; Treat parenthesis and string characters as punctuation when parsing the
|
;; Treat parenthesis and string characters as punctuation when parsing the
|
||||||
;; syntax of the output. Although we don't fontify output regions,
|
;; syntax of the output. Although we don't fontify output regions,
|
||||||
;; `syntax-ppss' still looks at the whole contents of the buffer. If there
|
;; `syntax-ppss' still looks at the whole contents of the buffer. If there
|
||||||
|
@ -1813,12 +1801,13 @@ VERBOSE has the same meaning as in
|
||||||
;; interfere with `syntax-ppss'. Note, this requires
|
;; interfere with `syntax-ppss'. Note, this requires
|
||||||
;; `parse-sexp-lookup-properties' to be non-nil so that `syntax-ppss' will
|
;; `parse-sexp-lookup-properties' to be non-nil so that `syntax-ppss' will
|
||||||
;; look at the `syntax-table' property.
|
;; look at the `syntax-table' property.
|
||||||
(goto-char (point-min))
|
(lambda ()
|
||||||
(skip-syntax-forward "^()\"")
|
(goto-char (point-min))
|
||||||
(while (not (eobp))
|
(skip-syntax-forward "^()\"")
|
||||||
(put-text-property (point) (1+ (point)) 'syntax-table '(1 . ?.))
|
(while (not (eobp))
|
||||||
(forward-char)
|
(put-text-property (point) (1+ (point)) 'syntax-table '(1 . ?.))
|
||||||
(skip-syntax-forward "^()\""))))
|
(forward-char)
|
||||||
|
(skip-syntax-forward "^()\"")))))
|
||||||
|
|
||||||
(defun jupyter-repl-font-lock-syntactic-face-function (face-fun state)
|
(defun jupyter-repl-font-lock-syntactic-face-function (face-fun state)
|
||||||
"Narrow to the input cell, use FACE-FUN to obtain the face given STATE."
|
"Narrow to the input cell, use FACE-FUN to obtain the face given STATE."
|
||||||
|
|
|
@ -1578,19 +1578,18 @@ last element being the newest element added to the history."
|
||||||
(should-error (jupyter-repl-cell-beginning-position))
|
(should-error (jupyter-repl-cell-beginning-position))
|
||||||
(should-error (jupyter-repl-cell-end-position)))))
|
(should-error (jupyter-repl-cell-end-position)))))
|
||||||
|
|
||||||
(ert-deftest jupyter-repl-cell-cond ()
|
(ert-deftest jupyter-repl-map-cells ()
|
||||||
:tags '(repl)
|
:tags '(repl)
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
(insert "foo")
|
(insert "foo")
|
||||||
(insert (propertize "bar" 'field 'cell-code))
|
(insert (propertize "bar" 'field 'cell-code))
|
||||||
(insert "baz")
|
(insert "baz")
|
||||||
(jupyter-repl-cell-cond
|
(let (input output)
|
||||||
(point-min) (point-max)
|
(jupyter-repl-map-cells (point-min) (point-max)
|
||||||
(should (equal (buffer-string) "bar"))
|
(lambda () (push (buffer-string) input))
|
||||||
(should (member (buffer-string) '("foo" "baz"))))
|
(lambda () (push (buffer-string) output)))
|
||||||
(jupyter-repl-cell-cond
|
(should (equal input '("bar")))
|
||||||
(point-min) (point-max)
|
(should (equal output '("baz" "foo"))))))
|
||||||
(should (equal (buffer-string) "bar")))))
|
|
||||||
|
|
||||||
(ert-deftest jupyter-repl-restart-kernel ()
|
(ert-deftest jupyter-repl-restart-kernel ()
|
||||||
:tags '(repl restart)
|
:tags '(repl restart)
|
||||||
|
|
Loading…
Add table
Reference in a new issue