Giter VIP home page Giter VIP logo

reveal's Introduction

logo Reveal: Read Eval Visualize Loop for Clojure

demo

Clojars Project Slack Channel

Rationale

Repl is a great window into a running program, but the textual nature of its output limits developer's ability to inspect the program: a text is not an object, and we are dealing with objects in the VM.

Reveal aims to solve this problem by creating an in-process repl output pane that makes inspecting values as easy as selecting an interesting datum. It recognizes the value of text as a universal interface, that's why its output looks like a text: you can select it, copy it, save it into a file. Unlike text, reveal output holds references to printed values, making inspecting selected value a matter of opening a context menu.

Unlike datafy/nav based tools, Reveal does not enforce a particular data representation for any given object, making it an open set — that includes datafy/nav as one of the available options. It does not use datafy/nav by default because in the absence of inter-process communication to datafy is to lose.

Not being limited to text, Reveal uses judicious syntax highlighting to aid in differentiating various objects: text java.lang.Integer looks differently depending on whether it was produced from a symbol or a class.

Reveal Pro

Reveal aims to be an extensible tool suitable for helping with development of any Clojure program. Reveal Pro provides a set of extensions that improve developer experience by providing more tools, so you can focus on your problem with data and knowledge you need, available as soon as you need it.

Documentation

You can find overview, setup instructions and more at vlaaad.github.io/reveal.

Versioning, stability, public and internal code

Reveal uses 1.MAJOR.REVISION versioning where:

  • 1 is a static prefix for compatibility with semantic versioning. Reveal should never introduce breaking changes, so if an update broke something, please file a bug report;
  • MAJOR is a number that is incremented when there are significant changes or improvements to Reveal;
  • REVISION is a commit number from the beginning of a history.

Reveal's compatibility promise applies to its public API: vlaaad.reveal ns, everything else is implementation detail that is subject to change. Reveal's UI and controls might change in the future.

reveal's People

Contributors

onetom avatar vlaaad avatar xificurc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

reveal's Issues

Reveal hangs after trying to open context menu

When I try to open the context menu, reveal sometimes hangs and throws exceptions in an endless loop. I could reproduce it only on my second screen and with the reveal window maximized (on Ubuntu with java 15). Also trying to open the context menu with a rather large output seems to be necessary.

The last entries in the stacktrace are:

java.lang.IllegalArgumentException: Both width and height must be >= 0
	at javafx.geometry.Rectangle2D.<init>(Rectangle2D.java:110)
	at vlaaad.reveal.popup$more_screen_space_below_QMARK_.invokeStatic(popup.clj:48)
	at vlaaad.reveal.popup$more_screen_space_below_QMARK_.invoke(popup.clj:34)
	at vlaaad.reveal.action_popup$view_impl.invokeStatic(action_popup.clj:162)
	at vlaaad.reveal.action_popup$view_impl.invoke(action_popup.clj:150)

So I added some prints to popup.clj see what is going on:

#object[javafx.stage.Screen 0xb116527 javafx.stage.Screen@a5a9bb0b bounds:Rectangle2D [minX = 2560.0, minY=0.0, maxX=4480.0, maxY=1080.0, width=1920.0, height=1080.0] visualBounds:Rectangle2D [minX = 2560.0, minY=27.0, maxX=4480.0, maxY=1080.0, width=1920.0, height=1053.0] dpi:91.0 outputScale:(1.0,1.0)]
#object[javafx.geometry.BoundingBox 0x4263f5f8 BoundingBox [minX:2590.01953125, minY:0.0, minZ:0.0, width:7.5048828125, height:16.99999999999998, depth:0.0, maxX:2597.5244140625, maxY:16.99999999999998, maxZ:0.0]]

Indeed it looks like the BoundingBox is not on my second screen and consequentially the logic from popup/more-screen-space-below? fails. I can however see no reason why the box is on the other screen and hope someone can help to figure out what is going on.

Happy to provide further information.

Problem with displaying clojure's sorted-set

When I use vlaaad.reveal.nrepl/middleware, I cannot print sorted-set anywhere. When an expression such as (apply sorted-set [1 2 3]) is evaluation in cider repl, I get the following error message

user> (apply sorted-set [1 2 3])
Error printing return value (ClassCastException) at clojure.lang.Keyword/compareTo (Keyword.java:114).
class java.lang.Long cannot be cast to class clojure.lang.Keyword (java.lang.Long is in module java.base of loader 'bootstrap'; clojure.lang.Keyword is in unnamed module of loader 'app')
user> 

If I send the result to tap, I don't get any error in repl

user> (tap> (apply sorted-set [1 2 3]))
true
user> 

However, the value is not printed in reveal window, no error either. This is the only data structure I'm having problem with reveal so far.

Reveal Pro crashes on startup

MacOS version: 13.0.1
Clojure version: 1.11.1.1189
OpenJDK version: 11.0.17

deps.edn:

{:aliases
  {:reveal {:extra-deps {dev.vlaaad/reveal-pro {:mvn/version "1.3.351"}}
 	         :ns-default vlaaad.reveal
	         :exec-fn repl}}}
% rlwrap clojure -X:reveal
DEPRECATED: Libs must be qualified, change deps-deploy => deps-deploy/deps-deploy (/Users/matthewnelson/.clojure/deps.edn)
DEPRECATED: Libs must be qualified, change expectations => expectations/expectations (/Users/matthewnelson/.clojure/deps.edn)
DEPRECATED: Libs must be qualified, change criterium => criterium/criterium (/Users/matthewnelson/.clojure/deps.edn)
DEPRECATED: Libs must be qualified, change proto-repl => proto-repl/proto-repl (/Users/matthewnelson/.clojure/deps.edn)
DEPRECATED: Libs must be qualified, change nrepl => nrepl/nrepl (/Users/matthewnelson/.clojure/deps.edn)
DEPRECATED: Libs must be qualified, change closh => closh/closh (/Users/matthewnelson/.clojure/deps.edn)
DEPRECATED: Libs must be qualified, change deps-deploy => deps-deploy/deps-deploy (/Users/matthewnelson/.clojure/deps.edn)
DEPRECATED: Libs must be qualified, change compliment => compliment/compliment (/Users/matthewnelson/.clojure/deps.edn)
Clojure 1.11.1
user=> 2022-11-10 11:17:37.256 java[25849:200357] *** Assertion failure in -[_NSTrackingAreaAKViewHelper removeTrackingRect:], _NSTrackingAreaAKManager.m:1585
2022-11-10 11:17:37.258 java[25849:200357] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '0x0 is an invalid NSTrackingRectTag. Common possible reasons for this are: 1. already removed this trackingRectTag, 2. Truncated the NSTrackingRectTag to 32bit at some point.'
*** First throw call stack:
(
	0   CoreFoundation                      0x00007ff80a66b43b __exceptionPreprocess + 242
	1   libobjc.A.dylib                     0x00007ff80a1bae25 objc_exception_throw + 48
	2   Foundation                          0x00007ff80b50cfb0 -[NSCalendarDate initWithCoder:] + 0
	3   AppKit                              0x00007ff80ddc8562 -[_NSTrackingAreaAKViewHelper removeTrackingRect:] + 190
	4   libglass.dylib                      0x00000001464ca4e9 -[GlassViewDelegate setFrameSize:] + 361
	5   libglass.dylib                      0x00000001464cfd68 -[GlassView3D setFrameSize:] + 88
	6   AppKit                              0x00007ff80d7543a1 -[NSView setFrame:] + 347
	7   libglass.dylib                      0x00000001464cfdc5 -[GlassView3D setFrame:] + 69
	8   AppKit                              0x00007ff80d7650f9 -[NSView resizeWithOldSuperviewSize:] + 694
	9   AppKit                              0x00007ff80d764a2a -[NSView resizeSubviewsWithOldSize:] + 488
	10  AppKit                              0x00007ff80d744206 -[NSView setFrameSize:] + 1446
	11  AppKit                              0x00007ff80d7543a1 -[NSView setFrame:] + 347
	12  AppKit                              0x00007ff80d7650f9 -[NSView resizeWithOldSuperviewSize:] + 694
	13  AppKit                              0x00007ff80d764a2a -[NSView resizeSubviewsWithOldSize:] + 488
	14  AppKit                              0x00007ff80d744206 -[NSView setFrameSize:] + 1446
	15  AppKit                              0x00007ff80d762e2d -[NSThemeFrame setFrameSize:] + 482
	16  AppKit                              0x00007ff80d7624f4 -[NSWindow _oldPlaceWindow:fromServer:] + 813
	17  AppKit                              0x00007ff80d760ae5 -[NSWindow _setFrameCommon:display:fromServer:] + 1656
	18  libglass.dylib                      0x00000001464c1acf -[GlassWindow(Java) _setFlipFrame:display:animate:] + 239
	19  libglass.dylib                      0x00000001464c15cc -[GlassWindow(Java) _setWindowFrameWithRect:withDisplay:withAnimate:] + 268
	20  libglass.dylib                      0x00000001464c181b -[GlassWindow(Java) _setBounds:y:xSet:ySet:w:h:cw:ch:] + 571
	21  libglass.dylib                      0x00000001464db2fe Java_com_sun_glass_ui_mac_MacWindow__1setBounds2 + 446
	22  ???                                 0x000000010bc74a10 0x0 + 4492577296
	23  ???                                 0x000000010bc6f267 0x0 + 4492554855
	24  ???                                 0x000000010bc6f267 0x0 + 4492554855
	25  ???                                 0x000000010bc6f267 0x0 + 4492554855
	26  ???                                 0x000000010bc6f2ac 0x0 + 4492554924
)
libc++abi: terminating with uncaught exception of type NSException

rlwrap: warning: clojure crashed, killed by SIGABRT.
rlwrap itself has not crashed, but for transparency,
it will now kill itself (without dumping core) with the same signal

warnings can be silenced by the --no-warnings (-n) option
zsh: abort      rlwrap clojure -X:reveal

Results are the same using % clojure -M:reveal and calling vlaaad.reveal/tap-log or vlaaad.reveal/repl. I've done this in a fresh directory and have deleted .cpcache on subsequent attempts.

Can't configure vlaaad.reveal.prefs from project.clj

I've been trying to use the following to set JAVA OPTS from a project.clj:

:profiles {:reveal {:dependencies [[vlaaad/reveal "1.2.184"]]
                      :repl-options {:nrepl-middleware [vlaaad.reveal.nrepl/middleware]}
                      :jvm-opts ["-Dfile.encoding=UTF8" "-Dvlaaad.reveal.prefs='{:font-family \"Consolas\" :font-size 15}'"]}}

It seems as though there is no way to escape the vlaaad.reveal.prefs properties in project.clj so that it can be read by Reveal. If you don't try to escape the double quotes using a backslash, then it would be parsed in the project.clj as closing the JAVA_OPTS. Using the escape seems to think it's already terminated as the error generated is that the "Consolas" class can't be loaded. I even tried to remove the :font-family so that it is just the :font-size and that wasn't parsed either.

WARNING: An illegal reflective access operation has occured

I am using Nixos 21.05 and received the following error:

❯ clj
-Sdeps '{:deps {vlaaad/reveal {:mvn/version "1.3.209"}}}'
-m vlaaad.reveal repl

libGL error: MESA-LOADER: failed to open iris: /nix/store/9df65igwjmf2wbw0gbrrgair6piqjgmi-glibc-2.31/lib/libc.so.6: version GLIBC_2.32' not found (required by /run/opengl-driver/lib/dri/iris_dri.so) (search paths /run/opengl-driver/lib/dri) libGL error: failed to load driver: iris libGL error: MESA-LOADER: failed to open iris: /nix/store/9df65igwjmf2wbw0gbrrgair6piqjgmi-glibc-2.31/lib/libc.so.6: version GLIBC_2.32' not found (required by /run/opengl-driver/lib/dri/iris_dri.so) (search paths /run/opengl-driver/lib/dri)
libGL error: failed to load driver: iris
libGL error: MESA-LOADER: failed to open swrast: /nix/store/9df65igwjmf2wbw0gbrrgair6piqjgmi-glibc-2.31/lib/libc.so.6: version `GLIBC_2.32' not found (required by /run/opengl-driver/lib/dri/swrast_dri.so) (search paths /run/opengl-driver/lib/dri)
libGL error: failed to load driver: swrast
Error in glXCreateNewContext, remote GLX is likely disabled
/nix/store/fwzgpr17cjsp5c7ax8sr10dpcqvb93p6-glib-networking-2.68.1/lib/gio/modules/libgiognutls.so: undefined symbol: g_tls_channel_binding_error_quark
Failed to load module: /nix/store/fwzgpr17cjsp5c7ax8sr10dpcqvb93p6-glib-networking-2.68.1/lib/gio/modules/libgiognutls.so
Clojure 1.10.1
user=> WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by vlaaad.reveal.font$fn__1886$fn__1887 to method com.sun.javafx.scene.text.FontHelper.getNativeFont(javafx.scene.text.Font)
WARNING: Please consider reporting this to the maintainers of vlaaad.reveal.font$fn__1886$fn__1887
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

Cursive setup with leiningen

How do I setup reveal with cursive and leiningen? I've created a profile with reveal as dep and an init-ns that calls reveal/repl. Doing this results in a read only repl.

NREPL integration crashes Java when trying to open context menu

GNU Emacs 28.0.90 (build 1, aarch64-apple-darwin21.1.0, NS appkit-2113.00 Version 12.0.1 (Build 21A559)) of 2021-12-08
;; CIDER 1.3.0-snapshot (package: 20220105.613), nREPL 0.9.0
;; Clojure 1.10.3, Java 17.0.1
user> (map (juxt identity #(System/getProperty %)) ["os.arch" "os.name" "os.version"])
(["os.arch" "aarch64"] ["os.name" "Mac OS X"] ["os.version" "12.1"])
user> (map (juxt identity #(System/getProperty %)) ["java.version" "java.runtime.name"])
(["java.version" "17.0.1"] ["java.runtime.name" "OpenJDK Runtime Environment"])

{vlaaad/reveal {:mvn/version "1.3.263"}} added to deps.edn, middlware added via .nrepl.edn as per docs. Once my REPL loads, I do (require '[vlaaad.reveal :as r]) #reveal/inspect (all-ns) and I see all NSes appear in the JavaFX window. However, as soon as I click on the JavaFX window, the process (and hence my NREPL) crashes with SIGABRT after ostensibly attempting to deref a null pointer:

Exception Type:        EXC_BAD_ACCESS (SIGABRT)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000000
Exception Codes:       0x0000000000000001, 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY

Happy to attach the full traceback if you think that's useful, but I think it's due to https://bugs.openjdk.java.net/browse/JDK-8275723 from hunting it down myself.

Good news: updating JavaFX fixes the issue. I'll submit a patch to cljfx and link this?

Accessibility inspector

Just wanted to say this project is the only way I know of right now to navigate data back from the REPL in sublime text, this project works really well with https://github.com/nasser/Socket, it's a godsend :D

Screenshot 2020-03-23 at 14 06 22

using

clj \
  -J-Dclojure.server.repl='{:port 5555 :accept vlaaad.reveal.prepl/-main}' \
  -Sdeps '{:deps {vlaaad/reveal {:mvn/version "0.1.0-ea13"}}}'

This issue is about that I can't really use it in the tiling manager I use: https://github.com/koekeishiya/yabai because the app seems "invisible" to Yabai and to the accessibility inspector that ships in macOS

@koekeishiya might be a good person to talk to if you'd like the rest of the OS and accessibility apps in general to see the REPL properly

Screenshot 2020-03-23 at 14 15 42

Chlorine: Submit function similar to REBL?

I'm trying to figure out how to use reveal with atom/chlorine. I currently use REBL in this setup. REBL is started via -m, and then chlorine can be configured to send to REBL as shown here: https://github.com/seancorfield/atom-chlorine-setup/blob/master/init.coffee#L50

As far as I can tell, that won't quite work with reveal as it stands, since the instance of the function required to submit things for evaluation requires have the result of calling make. I'll keep digging around, but if you have any thoughts on how to wire this up that would be fantastic.

Note on Leiningen

I have not yet jumped on the CLJ deps train, and use Leiningen. I am very interested to try out Reveal in my Lein-based main project, but am struggling with converting the CLJ-parameters to Lein.

Any input?

#question How do I send error logs of a running server to reveal?

Hi, thanks for the great work.
I'm running a ring server with reitit(router), and I want to send the error logs to reveal.

If I type directly into my local repl, reveal works great- it pretty prints the messages and does all sorts of stuffs for me. But it doesn't display any errors coming from the server - such as reitit coercion errors and SQL errors .. etc.

FYI, I'm running on local REPL with clojure.main, running with deps with parameters instructed in the introduction.
Do I need to add some configurations sending server errors to reveal?

Minimum JDK version

I executed the "Give it a try" section, but immediately got an error:

Syntax error (ClassNotFoundException) compiling at (cljfx/coerce.clj:1:1).
javafx.event.EventHandler

I suspect this is due to the fact that I use JDK8 (as so many still do...)? Perhaps useful to mention this in the documentation?

Memory leak?

I've been using reveal pretty extensively and it works very well.

However, I have been experiencing lots of OutOfMemory exceptions, and I wonder whether reveal is the cause.

Is there some sort of limit on the number of history items to store? If not, it would be useful to be able to set a limit on the amount of entries to keep in memory (like a ring buffer). Is this something that would be possible?

Recursive atoms cause stackoverflow error

This code will cause a stackoverflow error:

(def a (atom nil)) (def b (atom a)) (reset! a b)
a

Possible solutions are:

  1. print-method multimethod can be used to fix this for clojure repl. Maybe use that if it's available (https://clojuredocs.org/clojure.core/get-method)

  2. Don't print atoms target value in defstream IRef. It makes sense because atoms are used to opt out of the value semantics of clojure, and making recursive structures is a common use case.

:paragraph blocks

Thank you for this awesome open source contribution ❤️

I believe there's a missing case clause in vlaaad.reveal.stream here for the :paragraph value. Here's the stacktrace I encountered:

Exception in thread "reveal-stream-thread" java.lang.IllegalArgumentException: No matching clause: :paragraph
	at vlaaad.reveal.stream$format_xf$fn__151917.invoke(stream.clj:299)
	at vlaaad.reveal.stream$op$fn__151833.invoke(stream.clj:30)
	at vlaaad.reveal.stream$_EQ__GT_$fn__151830.invoke(stream.clj:24)
	at vlaaad.reveal.stream$_EQ__GT_$fn__151830.invoke(stream.clj:24)
	at clojure.lang.AFn.applyToHelper(AFn.java:156)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.lang.AFunction$1.doInvoke(AFunction.java:31)
	at clojure.lang.RestFn.invoke(RestFn.java:421)
	at vlaaad.reveal.stream$emit_xf$fn__151905.invoke(stream.clj:237)
	at vlaaad.reveal.ui$oneduce.invokeStatic(ui.clj:176)
	at vlaaad.reveal.ui$oneduce.invoke(ui.clj:171)
	at vlaaad.reveal.ui$make$fn__153639$fn__153640.invoke(ui.clj:276)
	at vlaaad.reveal.ui$make$fn__153639.invoke(ui.clj:273)
	at clojure.lang.AFn.run(AFn.java:22)
	at java.lang.Thread.run(Thread.java:745)

Versions:

  • vlaaad/reveal 0.1.0-ea13
  • Clojure 1.10.1
  • Java 8

Editor integration instructions using .nrepl.edn does not work for Emacs CIDER

Hi,

the .nrepl.edn Nrepl-based editor integration instructions unfortunately do not work for Emacs CIDER.

Nrepl-based editors

For development workflows that require nREPL (e.g. Calva, Emacs with Cider) Reveal has a middleware that will show evaluation results produced by nrepl: vlaaad.reveal.nrepl/middleware, you will need to add it to your middleware list. The minimum required version of nrepl is 0.6.0.

Example of using this middleware with command line nrepl entry point:

...

Alternatively, you can create .nrepl.edn file in your project directory that will be picked up by nrepl. Example .nrepl.edn file:

{:middleware [vlaaad.reveal.nrepl/middleware]}

...

To reproduce

  1. Create an empty deps.edn file:
{}
  1. In the same directory create a .nrepl.edn file with reveal middleware:
{:middleware [vlaaad.reveal.nrepl/middleware]}
  1. Open the deps.edn project file and jack in to the REPL with M-x cider-jack-in-clj RET.
  2. Cider brings up an nREPL and connects to it, but there is no reveal middleware injected, i.e. no reveal window pops up.

This is because cider makes uses the --middleware command line option when invoking nREPL which takes precedence over the corresponding :middleware [vlaaad.reveal.nrepl/middleware option in .nrepl:

Settings passed via the command-line interface will take precedence over settings specified via the configuration files.

Luckily, cider has a couple of configuration variables that can be set to download extra dependencies and inject nREPL middlewares (cider-jack-in-dependencies and cider-jack-in-nrepl-middlewares respectively), that can be used to load reveal as part of the REPL upbringing process (called jack-in in cider's nomenclature).

Perhaps you might want to add the following in the documentation.

To configure CIDER to download and inject revaal in the nREPL middleware list:

First add a function in your Emacs init file that configures CIDER to download and inject the given reveal version in the nREPL middleware list at jack in:

(defun reveal-cider-add! (version)
  "Injects vlaaad/reveal VERSION to cider's jack-in middleware list.

   It only takes effect on the current buffer."
  (require 'cider)
  (make-local-variable 'cider-jack-in-dependencies)
  (make-local-variable 'cider-jack-in-nrepl-middlewares)  
  (cider-add-to-alist 'cider-jack-in-dependencies "vlaaad/reveal" version)
  (add-to-list 'cider-jack-in-nrepl-middlewares "vlaaad.reveal.nrepl/middleware"))

Make sure you either eval the above function or restart Emacs for it to take effect and then open your Clojure project file (e.g. deps.edn) and invoke M-x add-file-local-variable-prop-line RET eval RET (reveal-cider-add! "1.3.270") RET so that the function is called every time the file is opened. It will add the following magic line as a comment at the top of the file:

;; -*- eval: (reveal-cider-add! "1.3.270"); -*-
...

Jacking in from the project file should inject the reveal middleware and bring up the reveal window at REPL startup. The above command can be added to any file you usually jack in from, not just the project file.

Alternatively, you can instruct Emacs to run the function from any Clojure in the project. To do so open a file at your project root directory (e.g. deps.edn), and invoke M-x add-dir-local-variable RET clojure-mode RET eval RET (reveal-cider-add! "1.3.270") RET. This will create a .dir-locals.el file that instructs Emacs to run the cider configuration function for any file that loads clojure-mode in the project directory tree:

;;; Directory Local Variables
;;; For more information see (info "(emacs) Directory Variables")

((clojure-mode . ((eval . (reveal-cider-add! "1.3.270")))))

You might need to reopen the Clojure files for the above changes to take effect. You will be prompted if you would like to eval the function when opening the file.

See Specifying File Variables and Directory Local Variables in the Emacs manual for more information.

There is yet a third, more intrusive way, to have cider always download and inject the reveal middleware in every jack in invocation irrespective of project file or directory, by adding the following into your emacs init file:

(require 'cider)
(cider-add-to-alist 'cider-jack-in-dependencies "vlaaad/reveal" "1.3.270")
(add-to-list 'cider-jack-in-nrepl-middlewares "vlaaad.reveal.nrepl/middleware")

I hope this is useful!

Thanks

Definitions from files with CRLF echo \r to Reveal

For example on Windows:

(def example-def-with-CRLF
  {:hello "world"
   "foo" :bar})

Will output:

(def example-def-with-CRLF\r
  {:hello "world"\r
   "foo" :bar})
=> #'user/example-def-with-CRLF

nRepl just shows:

#'user/example-def-with-CRLF
clj꞉user꞉>

So Reveal is perhaps a better response in that it shows something, but for Windows, the carriage return wouldn't be expected in this case. Perhaps Reveal needs a line ending setting with an environment default if it isn't overwritten? I could see this being the desired statement because it is what is being sent, but it also doesn't seem right.

Printing full message on eval

Sometimes a full metadata is printed for each evaluation.

So if I evaluate (+ 1 1) in my editor, I am getting

=> 6
{:request 
  {:transport ...
   :ns ...
   :session ...
   ...}
 :message {:id ...}}

It tends to be that as soon as it starts happening in a session, it will happen for every subsequent evaluation.

Fails to launch with java.lang.IllegalAccessException "cannot access class com.sun.javafx.scene.text.FontHelper"

I'm using the Java 17 JDK FX package on an arm-based Mac. When I run the "give it a try" code, it fails to launch and spits out the following:

java.lang.IllegalAccessException: class vlaaad.reveal.font$fn__279$fn__280 cannot access class com.sun.javafx.scene.text.FontHelper (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.scene.text to unnamed module @23e559f8
	at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:392)
	at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:674)
	at java.base/java.lang.reflect.Method.invoke(Method.java:560)
	at vlaaad.reveal.font$fn__279$fn__280.invoke(font.clj:24)
	at vlaaad.reveal.font$fn__300.invokeStatic(font.clj:66)
	at vlaaad.reveal.font$fn__300.invoke(font.clj:63)
	at clojure.lang.Delay.deref(Delay.java:42)
	at clojure.core$deref.invokeStatic(core.clj:2324)
	at clojure.core$deref.invoke(core.clj:2310)
	at vlaaad.reveal.font$char_width.invokeStatic(font.clj:69)
	at vlaaad.reveal.font$char_width.invokePrim(font.clj)
	at vlaaad.reveal.style$fn__342.invokeStatic(style.clj:46)
	at vlaaad.reveal.style$fn__342.invoke(style.clj:33)
	at clojure.lang.Delay.deref(Delay.java:42)
	at clojure.core$deref.invokeStatic(core.clj:2324)
	at clojure.core$deref.invoke(core.clj:2310)
	at vlaaad.reveal.ui$window.invokeStatic(ui.clj:596)
	at vlaaad.reveal.ui$window.invoke(ui.clj:563)
	at clojure.lang.AFn.applyToHelper(AFn.java:154)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.lang.Var.applyTo(Var.java:705)
	at clojure.core$apply.invokeStatic(core.clj:669)
	at clojure.core$apply.invoke(core.clj:662)
	at cljfx.lifecycle$wrap_map_desc$fn__1866.invoke(lifecycle.clj:446)
	at cljfx.lifecycle$eval1576$fn__1598$G__1563__1607.invoke(lifecycle.clj:17)
	at cljfx.renderer$render_component.invokeStatic(renderer.clj:57)
	at cljfx.renderer$render_component.invoke(renderer.clj:47)
	at cljfx.renderer$create$fn__2995.invoke(renderer.clj:77)
	at cljfx.renderer$perform_render$fn__2946.invoke(renderer.clj:23)
	at cljfx.renderer$perform_render.invokeStatic(renderer.clj:22)
	at cljfx.renderer$perform_render.invoke(renderer.clj:14)
	at cljfx.renderer$request_render$fn__2972$fn__2976.invoke(renderer.clj:44)
	at cljfx.renderer$request_render$fn__2972.invoke(renderer.clj:44)
	at clojure.lang.AFn.run(AFn.java:22)
	at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456)
	at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)

An illegal reflective access operation has occurred

$ clj -Sdeps '{:deps {vlaaad/reveal {:mvn/version "1.2.180"}}}' -m vlaaad.reveal repl
WARNING: When invoking clojure.main, use -M
Clojure 1.10.1
user=> WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by vlaaad.reveal.font$fn__1884$fn__1885 to method com.sun.javafx.scene.text.FontHelper.getNativeFont(javafx.scene.text.Font)
WARNING: Please consider reporting this to the maintainers of vlaaad.reveal.font$fn__1884$fn__1885
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

Dock icon on macOS

Hi @vlaaad,

First of all, thank you so much for all your work on Reveal. I think it's a very valuable tool in the Clojure space!

I would like to ask if you can include a bit of code to set the Dock icon on macOS. Currently Reveal has a very generic default icon, which makes it harder to recognise. The required code is quite simple. I'd make a pull request myself, but I'm not familiar with JavaFX so I have no idea how to do this, and for you it's likely quite easy. In Java it looks something like like this:

    try {
        URL iconURL = Main.class.getResource("ui/resources/[email protected]");
        Image image = new ImageIcon(iconURL).getImage();
        com.apple.eawt.Application.getApplication().setDockIconImage(image);
    } catch (Exception e) {
        // Won't work on Windows or Linux.
    }

The icon should preferably be 1024x1024 pixels.

If you don't have macOS to test this, maybe you can provide instructions for me on how to accomplish this in the Reveal source code, and I can make a PR and test it myself?

Thank you!

support more keybindings for scrolling

Love this amazing project. Was wondering if you would be open to more keybindings for scrolling. Perhaps as a config, or with such a sparse keymap so far, maybe both enabled since they don't seem to overlap:

  • vim: h, j, k, l
  • emacs: n, p, f, b

auto-scroll to bottom

Once I select something in the reveal window it stops auto-scrolling to the bottom, which is really annoying :) What am I doing wrong?

view:table max columns number is restricted to 16

Hi,

the maximum number of columns the view:table currently support is restricted to 16. This number seems to be arbitrary. My expectation would be that either there is no max limits or it is a much larger number.

To reproduce

  1. Evan an artificial table with 1 row and 17 columns
[(apply array-map (interleave (map (comp keyword str) (range 17)) (range)))]
  1. In the reveal window, right click on the opening square bracket and select view:table.

The table is displayed as a single column item, instead of a 17 column table:

item
{:0 0 :1 1 :2 2 :3 3 :4 4 :5 5 :6 6 :7 7 :8 8 :9 9 :10 10 :11 11 :12 12 :13 13 :14 14 :15 15 :16 16}

The max columns value is hardcoded in vlaaad.revial.view/infer-columns:

(defn- infer-columns [sample]
  (and (seq sample)
       (condp every? sample
         (some-fn map? nil?)
         (let [all-keys (mapcat keys sample)
               columns (distinct all-keys)
               column-count (count columns)
               cells (* (count sample) column-count)]
           (when (and (<= (/ cells 2) (count all-keys))
                      (<= 1 column-count 16))
             (for [k columns]
               {:header k :fn #(get % k no-val)})))

         map-entry?
         [{:header 'key :fn key} {:header 'val :fn val}]

         sequential?
         (let [counts (map count sample)
               column-count (apply max counts)
               cell-count (* (count sample) column-count)]
           (when (and (<= (/ cell-count 2) (reduce + counts))
                      (<= 1 column-count 16))
             (for [i (range column-count)]
               {:header i :fn #(nth % i no-val)})))

         nil)))

It is not obvious why a limit is imposed here (perhaps there is performance implications) , possible improvements I can think of:

  1. Remove max limit,
  2. Double max limit to 32 (satisfies my use case).
  3. Increase max limit considerably just to catch abused cases, e.g. to 1024.
  4. Make it a user option.

Happy to submit a PR.

Thanks

Errors running with cursive

Hi, when integrating with cursive/idea per the setup instructions (clojure.main, deps, and the following:

:reveal {:main-opts ["-m" "vlaaad.reveal" "repl"]
                    :extra-paths ["dev"]
                    :extra-deps  {vlaaad/reveal {:mvn/version "1.2.185"}}

Everything works fine from my startup namespace in dev/user.clj. However, switching namespaces doesn't seem to work at all. Evaluating any symbol refs nets you a Unable to resolve symbol: xxx in this context including, unfortunately load-file when you attempt to reload the current ns.

Any suggestions?

Better support for clojure.lang.PersistentQueue and other core Clojure data structures

Consider the following:

  (pop
   (->
    (clojure.lang.PersistentQueue/EMPTY)
    (conj "Item 1")
    (conj "Item 2")))

The output in Reveal is:
image

When shown as a table it is something which can be navigated, however this is the output for Cavla:
image

The representation of the data is actually easier to digest in Calva than it is in Reveal without navigating into the object itself. I believe this could be addressed with extending, but it also seems that core Clojure structures should naturally come with a friendlier representation OOTB.

Syntax error (ClassNotFoundException) compiling at (cljfx/coerce.clj:1:1).

probably not a problem in reveal but still... ;-)

radek@prdell ~> clj -Sdeps '{:deps {vlaaad/reveal {:mvn/version "0.1.0-ea13"}}}' -m vlaaad.reveal.repl
Downloading: vlaaad/reveal/0.1.0-ea13/reveal-0.1.0-ea13.pom from clojars
Downloading: cljfx/css/1.1.0/css-1.1.0.pom from clojars
Downloading: cljfx/cljfx/1.6.2/cljfx-1.6.2.pom from clojars
Downloading: vlaaad/reveal/0.1.0-ea13/reveal-0.1.0-ea13.jar from clojars
Downloading: cljfx/cljfx/1.6.2/cljfx-1.6.2-jdk8.jar from clojars
Downloading: cljfx/css/1.1.0/css-1.1.0.jar from clojars
Downloading: cljfx/cljfx/1.6.2/cljfx-1.6.2.jar from clojars
Syntax error (ClassNotFoundException) compiling at (cljfx/coerce.clj:1:1).
javafx.event.EventHandler

Full report at:
/tmp/clojure-1110569930540587772.edn

ClassNotFound: com.sun.javafx.tk.Toolkit

{:clojure.main/message
 "Syntax error (ClassNotFoundException) compiling at (vlaaad/reveal/font.clj:1:1).\ncom.sun.javafx.tk.Toolkit\n",
 :clojure.main/triage
 {:clojure.error/phase :compile-syntax-check,
  :clojure.error/line 1,
  :clojure.error/column 1,
  :clojure.error/source "font.clj",
  :clojure.error/path "vlaaad/reveal/font.clj",
  :clojure.error/class java.lang.ClassNotFoundException,
  :clojure.error/cause "com.sun.javafx.tk.Toolkit"},
 :clojure.main/trace
 {:via
  [{:type clojure.lang.Compiler$CompilerException,
    :message "Syntax error compiling at (vlaaad/reveal/font.clj:1:1).",
    :data
    {:clojure.error/phase :compile-syntax-check,
     :clojure.error/line 1,
     :clojure.error/column 1,
     :clojure.error/source "vlaaad/reveal/font.clj"},
    :at [clojure.lang.Compiler load "Compiler.java" 7648]}
   {:type java.lang.ClassNotFoundException,
    :message "com.sun.javafx.tk.Toolkit",
    :at
    [java.net.URLClassLoader findClass "URLClassLoader.java" 471]}],
  :trace
  [[java.net.URLClassLoader findClass "URLClassLoader.java" 471]
   [clojure.lang.DynamicClassLoader
    findClass
    "DynamicClassLoader.java"
    69]
   [java.lang.ClassLoader loadClass "ClassLoader.java" 588]
   [clojure.lang.DynamicClassLoader
    loadClass
    "DynamicClassLoader.java"
    77]
   [java.lang.ClassLoader loadClass "ClassLoader.java" 521]
   [java.lang.Class forName0 "Class.java" -2]
   [java.lang.Class forName "Class.java" 398]
   [clojure.lang.RT classForName "RT.java" 2211]
   [clojure.lang.RT classForNameNonLoading "RT.java" 2224]
   [vlaaad.reveal.font$eval150$loading__6721__auto____151
    invoke
    "font.clj"
    1]
   [vlaaad.reveal.font$eval150 invokeStatic "font.clj" 1]
   [vlaaad.reveal.font$eval150 invoke "font.clj" 1]
   [clojure.lang.Compiler eval "Compiler.java" 7177]
   [clojure.lang.Compiler eval "Compiler.java" 7166]
   [clojure.lang.Compiler load "Compiler.java" 7636]
   [clojure.lang.RT loadResourceScript "RT.java" 381]
   [clojure.lang.RT loadResourceScript "RT.java" 372]
   [clojure.lang.RT load "RT.java" 459]
   [clojure.lang.RT load "RT.java" 424]
   [clojure.core$load$fn__6839 invoke "core.clj" 6126]
   [clojure.core$load invokeStatic "core.clj" 6125]
   [clojure.core$load doInvoke "core.clj" 6109]
   [clojure.lang.RestFn invoke "RestFn.java" 408]
   [clojure.core$load_one invokeStatic "core.clj" 5908]
   [clojure.core$load_one invoke "core.clj" 5903]
   [clojure.core$load_lib$fn__6780 invoke "core.clj" 5948]
   [clojure.core$load_lib invokeStatic "core.clj" 5947]
   [clojure.core$load_lib doInvoke "core.clj" 5928]
   [clojure.lang.RestFn applyTo "RestFn.java" 142]
   [clojure.core$apply invokeStatic "core.clj" 667]
   [clojure.core$load_libs invokeStatic "core.clj" 5985]
   [clojure.core$load_libs doInvoke "core.clj" 5969]
   [clojure.lang.RestFn applyTo "RestFn.java" 137]
   [clojure.core$apply invokeStatic "core.clj" 667]
   [clojure.core$require invokeStatic "core.clj" 6007]
   [clojure.core$require doInvoke "core.clj" 6007]
   [clojure.lang.RestFn invoke "RestFn.java" 421]
   [vlaaad.reveal.stream$eval144$loading__6721__auto____145
    invoke
    "stream.clj"
    1]
   [vlaaad.reveal.stream$eval144 invokeStatic "stream.clj" 1]
   [vlaaad.reveal.stream$eval144 invoke "stream.clj" 1]
   [clojure.lang.Compiler eval "Compiler.java" 7177]
   [clojure.lang.Compiler eval "Compiler.java" 7166]
   [clojure.lang.Compiler load "Compiler.java" 7636]
   [clojure.lang.RT loadResourceScript "RT.java" 381]
   [clojure.lang.RT loadResourceScript "RT.java" 372]
   [clojure.lang.RT load "RT.java" 459]
   [clojure.lang.RT load "RT.java" 424]
   [clojure.core$load$fn__6839 invoke "core.clj" 6126]
   [clojure.core$load invokeStatic "core.clj" 6125]
   [clojure.core$load doInvoke "core.clj" 6109]
   [clojure.lang.RestFn invoke "RestFn.java" 408]
   [clojure.core$load_one invokeStatic "core.clj" 5908]
   [clojure.core$load_one invoke "core.clj" 5903]
   [clojure.core$load_lib$fn__6780 invoke "core.clj" 5948]
   [clojure.core$load_lib invokeStatic "core.clj" 5947]
   [clojure.core$load_lib doInvoke "core.clj" 5928]
   [clojure.lang.RestFn applyTo "RestFn.java" 142]
   [clojure.core$apply invokeStatic "core.clj" 667]
   [clojure.core$load_libs invokeStatic "core.clj" 5985]
   [clojure.core$load_libs doInvoke "core.clj" 5969]
   [clojure.lang.RestFn applyTo "RestFn.java" 137]
   [clojure.core$apply invokeStatic "core.clj" 667]
   [clojure.core$require invokeStatic "core.clj" 6007]
   [clojure.core$require doInvoke "core.clj" 6007]
   [clojure.lang.RestFn invoke "RestFn.java" 619]
   [vlaaad.reveal.prepl$eval138$loading__6721__auto____139
    invoke
    "prepl.clj"
    1]
   [vlaaad.reveal.prepl$eval138 invokeStatic "prepl.clj" 1]
   [vlaaad.reveal.prepl$eval138 invoke "prepl.clj" 1]
   [clojure.lang.Compiler eval "Compiler.java" 7177]
   [clojure.lang.Compiler eval "Compiler.java" 7166]
   [clojure.lang.Compiler load "Compiler.java" 7636]
   [clojure.lang.RT loadResourceScript "RT.java" 381]
   [clojure.lang.RT loadResourceScript "RT.java" 372]
   [clojure.lang.RT load "RT.java" 459]
   [clojure.lang.RT load "RT.java" 424]
   [clojure.core$load$fn__6839 invoke "core.clj" 6126]
   [clojure.core$load invokeStatic "core.clj" 6125]
   [clojure.core$load doInvoke "core.clj" 6109]
   [clojure.lang.RestFn invoke "RestFn.java" 408]
   [clojure.core$load_one invokeStatic "core.clj" 5908]
   [clojure.core$load_one invoke "core.clj" 5903]
   [clojure.core$load_lib$fn__6780 invoke "core.clj" 5948]
   [clojure.core$load_lib invokeStatic "core.clj" 5947]
   [clojure.core$load_lib doInvoke "core.clj" 5928]
   [clojure.lang.RestFn applyTo "RestFn.java" 142]
   [clojure.core$apply invokeStatic "core.clj" 667]
   [clojure.core$load_libs invokeStatic "core.clj" 5985]
   [clojure.core$load_libs doInvoke "core.clj" 5969]
   [clojure.lang.RestFn applyTo "RestFn.java" 137]
   [clojure.core$apply invokeStatic "core.clj" 667]
   [clojure.core$require invokeStatic "core.clj" 6007]
   [clojure.main$main_opt invokeStatic "main.clj" 514]
   [clojure.main$main_opt invoke "main.clj" 510]
   [clojure.main$main invokeStatic "main.clj" 664]
   [clojure.main$main doInvoke "main.clj" 616]
   [clojure.lang.RestFn applyTo "RestFn.java" 137]
   [clojure.lang.Var applyTo "Var.java" 705]
   [clojure.main main "main.java" 40]],
  :cause "com.sun.javafx.tk.Toolkit",
  :phase :compile-syntax-check}}

log support

Hi, thanks for this interesting library! Before diving into the code or looking for fixes I'd like to get an understanding of reveal's scope. I develop in emacs with cider so I'm using the nrepl middleware route to start up reveal. This leaves me with 2 places to look at output, the emacs nrepl buffer and reveal's window. Values show up in both just fine but the logs get only routed to the nrepl buffer. There was 1 time when the logs actually went into reveal as well, so I'm not quite sure what is considered "correct" behavior. I'm using timbre for logging and routing slf4j logs into it.

Is reveal's purpose to be a general REPL replacement? If so then I'd like to get the logs working. Otherwise I need to keep the nrepl buffer around as well. As for my personal preference - I'd like to have just one around, I don't type into the REPL anyway.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.