-
-
Notifications
You must be signed in to change notification settings - Fork 645
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for displaying various images #2248
Conversation
cider-repl.el
Outdated
(lambda (buffer pprint-out) | ||
(cider-repl-emit-result buffer pprint-out (not after-first-result-chunk)) | ||
(setq after-first-result-chunk t)) | ||
(lambda (buffer value content-type) | ||
(if-let ((handler (cdr (assoc content-type cider-repl-content-type-handler-alist)))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if-let
is obsolete. Emacs ≥26.1 uses if-let*
, as does CIDER (via cider-compat.el
).
@@ -764,7 +764,8 @@ to the REPL." | |||
(defun nrepl-make-response-handler (buffer value-handler stdout-handler | |||
stderr-handler done-handler | |||
&optional eval-error-handler | |||
pprint-out-handler) | |||
pprint-out-handler | |||
content-type-handler) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Docstring should mention this and say what it does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love it how ridiculous this function is at that point. :D It's certainly one of the prime candidates for some massive refactorings.
cider-repl.el
Outdated
(create-image (if datap (base64-decode-string image) image) type datap | ||
:margin cider-repl-image-margin)) | ||
|
||
(setq cider-repl-content-type-handler-alist |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
defvar
/defcustom
?
nrepl-client.el
Outdated
(when (buffer-live-p buffer) | ||
(with-current-buffer buffer | ||
(when (and ns (not (derived-mode-p 'clojure-mode))) | ||
(cider-set-buffer-ns ns)))) | ||
(cond (value | ||
(cond ((and content content-type content-type-handler) | ||
(funcall content-type-handler buffer content content-type)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
content-type-handler
is called w/ only 3 args, while the functions in cider-repl-content-type-handler-alist
can take 4.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. What happens here is that the content-type-handler
function is called as (buff content content-type)
, it does its own internal dispatch, chooses a handler implementatiion (if any) and defers to that handler.
Because of the current mechanics of CIDER's various insertion functions, the arguments &optional show-prefix bol
seem to be required in order to ensure that the user's prefix configuration is respected. The precise behavior of the bol
flag is ... not obvious so I just retained it blindly.
I'd like to see the way that the REPL handles marks cleaned up to maintain one set of marks per eval requests which would I think simplify some of this logic and fix some interesting behavior where output / errors from threads forked by previous evals can become interleaved with the latest output and its value(s).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that'd be nice. Unfortunately there's a ton of legacy in the REPL code - much of it came straight from SLIME and was barely updated afterwards.
cider-repl.el
Outdated
(cider-repl-emit-result buffer pprint-out (not after-first-result-chunk)) | ||
(setq after-first-result-chunk t)) | ||
(lambda (buffer value content-type) | ||
(if-let ((handler (cdr (assoc content-type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if-let
-> if-let*
cider-repl.el
Outdated
(create-image (if datap (base64-decode-string image) image) type datap | ||
:margin cider-repl-image-margin)) | ||
|
||
(defun cider-repl-handle-jpeg (buffer image &optional show-prefix bol) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a lot of repetition w/ these functions. Seems like a cider-repl-handle-image
that dispatches on image type could eliminate that. There's apply-partially
if you need it.
cider-repl.el
Outdated
("image/jpeg;base64" . #'cider-repl-handle-jpeg64) | ||
("image/png". #'cider-repl-handle-png) | ||
("image/png;base64" . #'cider-repl-handle-png64)) | ||
"Association list from content-types to handlers for inserting nREPL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just alist
is fine.
@arrdem in the screenshot, seems it is
|
cider-repl.el
Outdated
(set-marker cider-repl-prompt-start-mark (point) buffer)))) | ||
(cider-repl--show-maximum-output))) | ||
|
||
(defcustom cider-repl-image-margin 10 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably we should also add some defcustom to turn this functionality off in case someone doesn't like it, or the initial implementation causes problems in some cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with this. Should have an option to disable it to avoid early stage problems.
Overall things look good to me (apart from the failing build).
I guess one way to make things configurable would be set the configuration on the Emacs side and send it to the middleware as part of some "init" message when the connection is being established. I dislike in the Emacs handlers that even though they don't have to support text, they current support params that make sense only for text output. I've got two questions:
I'd be really nice to add support for this for interactive evaluation as well, which probably means some of the image handling code, shouldn't live in the REPL source code. E.g. you can show resulting images in an overlay or a dedicated result buffer, but obviously we can't show them in the minibuffer. :-) Btw, I'm wondering about the special way you've treated |
About image too wide problem, I guess Emacs handle this. Org-mode has similar function to specify image with. I don't know how it is implemented. Even more, the image width can be smarter based on current Emacs window width. |
One more thing - does clearing output in the REPL work properly for images? This certainly needs to be tested. |
Not great but this prevents the pretty-print middleware from interacting with the image / content-type middleware.
This is really cool. Is is possible to get it working with |
Fixes #1510
This is my second-pass changeset to implement support for embedding images in the REPL. It's probably got some sharp edges - my elisp isn't that good - but it definitely functions as advertised. I'd appreocate criticism on how the handlers should be made more configurable both on the nREPL side of the changeset (clojure-emacs/cider-nrepl#517) and on the emacs side.
Demo
Before submitting the PR make sure the following things have been done (and denote this
by checking the relevant checkboxes):
make test
)make lint
) which is based onelisp-lint
and includescheckdoc
, check-declare, packaging metadata, indentation, and trailing whitespace checks.Thanks!
If you're just starting out to hack on CIDER you might find this section of its
manual extremely useful.