-
-
Notifications
You must be signed in to change notification settings - Fork 648
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
Merged
Merged
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
0ed1b73
Initial cut at image support
arrdem 265e6e0
Use content to disambiguate from value
arrdem 1508d28
Don't need to substring anymore
arrdem f7fecad
Get base64 decoding of images working
arrdem 80038b3
Format
arrdem eb6f27e
Factor image insertion a bit better, add a customizable margin
arrdem 0242edd
Re-indent for the linter
arrdem 41efe47
Update CHANGELOG
arrdem 9e209ef
Add to Author list
arrdem 467192f
Add to Author list
arrdem 3cb624f
if-let -> if-let*
arrdem 58bbea5
Factor into defcustoms and some fns
arrdem bce72dc
Document the changes to nrepl-make-response-handler
arrdem 0d7db17
Love to spend my time fixing format issues
arrdem a6c0993
Add :type for the linter
arrdem fb707f5
Add a content-type REPL option akin to the pprint option
arrdem 0864d6d
Update the handler signature to reflect that content-type is now a 2-…
arrdem 6baabf7
And working again atop 7a838de380f10acf813b1c22175a3f89a5a94956
arrdem 964965e
Docstring
arrdem 62bb7f0
Add another docstring
arrdem 82c8f3b
Handle content-transfer-encoding magically
arrdem f37f51b
Don't manually manage base64 decoding anymore
arrdem e243028
Whitespace
arrdem 6ca461e
Whitespace
arrdem e56ce60
More whitespace
arrdem File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ | |
;; Artur Malabarba <[email protected]> | ||
;; Hugo Duncan <[email protected]> | ||
;; Steve Purcell <[email protected]> | ||
;; Reid McKenzie <[email protected]> | ||
|
||
;; This program is free software: you can redistribute it and/or modify | ||
;; it under the terms of the GNU General Public License as published by | ||
|
@@ -112,7 +113,7 @@ If this is set to nil, no re-centering takes place." | |
:package-version '(cider . "0.11.0")) | ||
|
||
(defcustom cider-repl-use-pretty-printing nil | ||
"Control whether the results in REPL are pretty-printed or not. | ||
"Control whether results in the REPL are pretty-printed or not. | ||
The `cider-toggle-pretty-printing' command can be used to interactively | ||
change the setting's value." | ||
:type 'boolean | ||
|
@@ -127,6 +128,13 @@ defaults to the variable `fill-column'." | |
:group 'cider-repl | ||
:package-version '(cider . "0.15.0")) | ||
|
||
(defcustom cider-repl-use-content-types t | ||
"Control whether REPL results are presented using content-type information or not. | ||
The `cider-toggle-content-types' command can be used to interactively | ||
change the setting's value." | ||
:type 'boolean | ||
:group 'cider-repl) | ||
|
||
(defcustom cider-repl-use-clojure-font-lock t | ||
"Non-nil means to use Clojure mode font-locking for input and result. | ||
Nil means that `cider-repl-input-face' and `cider-repl-result-face' | ||
|
@@ -799,24 +807,133 @@ the symbol." | |
t))) | ||
(t t)))) | ||
|
||
(defun cider-repl--display-image (buffer image &optional show-prefix bol string) | ||
"Insert IMAGE into BUFFER at the current point. | ||
|
||
For compatibility with the rest of CIDER's REPL machinery, supports | ||
SHOW-PREFIX and BOL." | ||
(with-current-buffer buffer | ||
(save-excursion | ||
(cider-save-marker cider-repl-output-start | ||
(cider-save-marker cider-repl-output-end | ||
(goto-char cider-repl-input-start-mark) | ||
(when (and bol (not (bolp))) | ||
(insert-before-markers "\n")) | ||
(when show-prefix | ||
(insert-before-markers | ||
(propertize cider-repl-result-prefix 'font-lock-face 'font-lock-comment-face))) | ||
(insert-image image string) | ||
(set-marker cider-repl-input-start-mark (point) buffer) | ||
(set-marker cider-repl-prompt-start-mark (point) buffer)))) | ||
(cider-repl--show-maximum-output)) | ||
t) | ||
|
||
(defcustom cider-repl-image-margin 10 | ||
"Specifies the margin to be applied to images displayed in the REPL. | ||
|
||
Either a single number of pixels - interpreted as a symmetric margin, or | ||
pair of numbers `(x . y)' encoding an arbitrary margin." | ||
:type '(choice integer (vector integer integer)) | ||
:group 'cider-repl | ||
:package-version '(cider . "0.17.0")) | ||
|
||
(defun cider-repl--image (data type datap) | ||
"A helper for creating images with CIDER's image options. | ||
|
||
FILE-OR-DATA is either the path to an image or its base64 coded data. TYPE | ||
is a symbol indicating the image type. DATAP indicates whether the image is | ||
the raw image data or a filename. | ||
|
||
Returns an image instance with a margin per `cider-repl-image-margin'." | ||
(create-image data type datap | ||
:margin cider-repl-image-margin)) | ||
|
||
(defun cider-repl-handle-jpeg (_type buffer image &optional show-prefix bol) | ||
"A handler for inserting a jpeg IMAGE into a repl BUFFER. | ||
Part of the default `cider-repl-content-type-handler-alist'." | ||
(cider-repl--display-image buffer | ||
(cider-repl--image image 'jpeg t) | ||
show-prefix bol image)) | ||
|
||
(defun cider-repl-handle-png (_type buffer image &optional show-prefix bol) | ||
"A handler for inserting a png IMAGE into a repl BUFFER. | ||
Part of the default `cider-repl-content-type-handler-alist'." | ||
(cider-repl--display-image buffer | ||
(cider-repl--image image 'png t) | ||
show-prefix bol image)) | ||
|
||
(defun cider-repl-handle-external-body (type buffer _ &optional show-prefix bol) | ||
"Handler for slurping external content into BUFFER. | ||
Handles an external-body TYPE by issuing a slurp request to fetch the content." | ||
(if-let* ((args (second type)) | ||
(access-type (nrepl-dict-get args "access-type"))) | ||
(nrepl-send-request | ||
(list "op" "slurp" "url" (nrepl-dict-get args "URL")) | ||
(cider-repl-handler buffer) | ||
(cider-current-connection))) | ||
nil) | ||
|
||
(defcustom cider-repl-content-type-handler-alist | ||
`(("message/external-body" . ,#'cider-repl-handle-external-body) | ||
("image/jpeg" . ,#'cider-repl-handle-jpeg) | ||
("image/png" . ,#'cider-repl-handle-png)) | ||
"Association list from content-types to handlers. | ||
|
||
Handlers must be functions of two required and two optional arguments - the | ||
REPL buffer to insert into, the value of the given content type as a raw | ||
string, the REPL's show prefix as any and an `end-of-line' flag. | ||
|
||
The return value of the handler should be a flag, indicating whether or not | ||
the REPL is ready for a prompt to be displayed. Most handlers should return | ||
`t', as the content-type response is (currently) an alternative to the | ||
value response. However for handlers which themselves issue subsequent | ||
nREPL ops, it may be convenient to prevent inserting a prompt." | ||
:group 'cider-repl | ||
:package-version '(cider . "0.17.0")) | ||
|
||
(defun cider-repl-handler (buffer) | ||
"Make an nREPL evaluation handler for the REPL BUFFER." | ||
(nrepl-make-response-handler buffer | ||
(let (after-first-result-chunk) | ||
(lambda (buffer value) | ||
(cider-repl-emit-result buffer value (not after-first-result-chunk) t) | ||
(setq after-first-result-chunk t))) | ||
(lambda (buffer out) | ||
(cider-repl-emit-stdout buffer out)) | ||
(lambda (buffer err) | ||
(cider-repl-emit-stderr buffer err)) | ||
(lambda (buffer) | ||
(cider-repl-emit-prompt buffer)) | ||
nrepl-err-handler | ||
(let (after-first-result-chunk) | ||
(lambda (buffer pprint-out) | ||
(cider-repl-emit-result buffer pprint-out (not after-first-result-chunk)) | ||
(setq after-first-result-chunk t))))) | ||
(let (after-first-result-chunk | ||
(show-prompt t)) | ||
(nrepl-make-response-handler | ||
buffer | ||
(lambda (buffer value) | ||
(cider-repl-emit-result buffer value (not after-first-result-chunk) t) | ||
(setq after-first-result-chunk t)) | ||
(lambda (buffer out) | ||
(cider-repl-emit-stdout buffer out)) | ||
(lambda (buffer err) | ||
(cider-repl-emit-stderr buffer err)) | ||
(lambda (buffer) | ||
(when show-prompt | ||
(cider-repl-emit-prompt buffer) | ||
(let ((win (get-buffer-window (current-buffer) t))) | ||
(when win | ||
(with-selected-window win | ||
(set-window-point win cider-repl-input-start-mark)) | ||
(cider-repl--show-maximum-output))))) | ||
nrepl-err-handler | ||
(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* ((content-attrs (second content-type)) | ||
(content-type* (first content-type)) | ||
(handler (cdr (assoc content-type* | ||
cider-repl-content-type-handler-alist)))) | ||
(setq after-first-result-chunk t | ||
show-prompt (funcall handler content-type buffer value | ||
(not after-first-result-chunk) t)) | ||
(progn (cider-repl-emit-result buffer value (not after-first-result-chunk) t) | ||
(setq after-first-result-chunk t))))))) | ||
|
||
(defun cider--repl-request-plist (right-margin &optional pprint-fn) | ||
"Plist to be appended to generic eval requests, as for the REPL. | ||
PPRINT-FN and RIGHT-MARGIN are as in `cider--nrepl-pprint-request-plist'." | ||
(nconc (when cider-repl-use-pretty-printing | ||
(cider--nrepl-pprint-request-plist right-margin pprint-fn)) | ||
(when cider-repl-use-content-types | ||
(cider--nrepl-content-type-plist)))) | ||
|
||
(defun cider-repl--send-input (&optional newline) | ||
"Go to the end of the input and send the current input. | ||
|
@@ -858,9 +975,7 @@ If NEWLINE is true then add a newline at the end of the input." | |
(cider-current-ns) | ||
(line-number-at-pos input-start) | ||
(cider-column-number-at-pos input-start) | ||
(unless (or (not cider-repl-use-pretty-printing) | ||
(string-match-p "\\`[ \t\r\n]*\\'" input)) | ||
(cider--nrepl-pprint-request-plist (cider--pretty-print-width)))))))) | ||
(cider--repl-request-plist (cider--pretty-print-width))))))) | ||
|
||
(defun cider-repl-return (&optional end-of-input) | ||
"Evaluate the current input string, or insert a newline. | ||
|
@@ -936,6 +1051,13 @@ text property `cider-old-input'." | |
fill-column | ||
80)) | ||
|
||
(defun cider-repl-toggle-content-types () | ||
"Toggle content-type rendering in the REPL." | ||
(interactive) | ||
(setq cider-repl-use-content-types (not cider-repl-use-content-types)) | ||
(message "Content-type support in REPL %s." | ||
(if cider-repl-use-content-types "enabled" "disabled"))) | ||
|
||
(defun cider-repl-switch-to-other () | ||
"Switch between the Clojure and ClojureScript REPLs for the current project." | ||
(interactive) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ | |
;; Artur Malabarba <[email protected]> | ||
;; Hugo Duncan <[email protected]> | ||
;; Steve Purcell <[email protected]> | ||
;; Reid McKenzie <[email protected]> | ||
;; | ||
;; This program is free software: you can redistribute it and/or modify | ||
;; it under the terms of the GNU General Public License as published by | ||
|
@@ -764,7 +765,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) | ||
"Make a response handler for connection BUFFER. | ||
A handler is a function that takes one argument - response received from | ||
the server process. The response is an alist that contains at least 'id' | ||
|
@@ -773,20 +775,35 @@ and 'session' keys. Other standard response keys are 'value', 'out', 'err', | |
|
||
The presence of a particular key determines the type of the response. For | ||
example, if 'value' key is present, the response is of type 'value', if | ||
'out' key is present the response is 'stdout' etc. Depending on the type, | ||
the handler dispatches the appropriate value to one of the supplied | ||
handlers: VALUE-HANDLER, STDOUT-HANDLER, STDERR-HANDLER, DONE-HANDLER, | ||
EVAL-ERROR-HANDLER, and PPRINT-OUT-HANDLER. If the optional | ||
EVAL-ERROR-HANDLER is nil, the default `nrepl-err-handler' is used. If any | ||
of the other supplied handlers are nil nothing happens for the | ||
corresponding type of response." | ||
'out' key is present the response is 'stdout' etc. | ||
|
||
Depending on the type, the handler dispatches the appropriate value to one | ||
of the supplied handlers: VALUE-HANDLER, STDOUT-HANDLER, STDERR-HANDLER, | ||
DONE-HANDLER, EVAL-ERROR-HANDLER, PPRINT-OUT-HANDLER and | ||
CONTENT-TYPE-HANDLER. | ||
|
||
Handlers are functions of the buffer and the value they handle, except for | ||
the optional CONTENT-TYPE-HANDLER which should be a function of the buffer, | ||
content, the content-type to be handled as a list `(type attrs)'. | ||
|
||
If the optional EVAL-ERROR-HANDLER is nil, the default `nrepl-err-handler' | ||
is used. If any of the other supplied handlers are nil nothing happens for | ||
the corresponding type of response." | ||
(lambda (response) | ||
(nrepl-dbind-response response (value ns out err status id pprint-out) | ||
(nrepl-dbind-response response (content-type content-transfer-encoding body | ||
value ns out err status id | ||
pprint-out) | ||
(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-type content-type-handler) | ||
(funcall content-type-handler buffer | ||
(if (string= content-transfer-encoding "base64") | ||
(base64-decode-string body) | ||
body) | ||
content-type)) | ||
(value | ||
(when value-handler | ||
(funcall value-handler buffer value))) | ||
(out | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.