emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/cider ded24d8929: Inspector: render Java items using `java


From: ELPA Syncer
Subject: [nongnu] elpa/cider ded24d8929: Inspector: render Java items using `java-mode` syntax coloring (#3547)
Date: Mon, 23 Oct 2023 16:00:02 -0400 (EDT)

branch: elpa/cider
commit ded24d8929c04e8492fb9f99c91110b0cb897328
Author: vemv <vemv@users.noreply.github.com>
Commit: GitHub <noreply@github.com>

    Inspector: render Java items using `java-mode` syntax coloring (#3547)
    
    Fixes https://github.com/clojure-emacs/cider/issues/3546
---
 CHANGELOG.md                  |   4 +
 cider-docstring.el            |  10 +-
 cider-inspector.el            |  36 +++-
 test/cider-inspector-tests.el | 373 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 407 insertions(+), 16 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 753aa84b72..ebb5569a76 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,10 @@
 
 ## master (unreleased)
 
+### Changes
+
+- [#3546](https://github.com/clojure-emacs/cider/issues/3546): Inspector: 
render Java items using `java-mode` syntax coloring.
+
 ### Bugs fixed
 
 - Inspector: avoid `Symbol's value as variable is void: 
text-scale-mode-amount` under certain Emacs clients.
diff --git a/cider-docstring.el b/cider-docstring.el
index 56c68022c4..c991615bd5 100644
--- a/cider-docstring.el
+++ b/cider-docstring.el
@@ -29,19 +29,11 @@
 (require 'cl-lib)
 (require 'shr)
 
-(defun cider--to-java-string (s)
-  "Convert string S to a Java-formatted string with syntax highlighting."
-  (with-temp-buffer
-    (insert s)
-    (java-mode)
-    (font-lock-ensure)
-    (buffer-string)))
-
 (defsubst cider--render-pre* (dom)
   "Render DOM nodes, formatting them them as Java if they are strings."
   (dolist (sub (dom-children dom))
     (if (stringp sub)
-        (shr-insert (cider--to-java-string sub))
+        (shr-insert (cider-font-lock-as 'java-mode sub))
       (shr-descend sub))))
 
 (defun cider--render-pre (dom)
diff --git a/cider-inspector.el b/cider-inspector.el
index a94000fe9f..4952e75b06 100644
--- a/cider-inspector.el
+++ b/cider-inspector.el
@@ -427,20 +427,42 @@ MAX-COLL-SIZE if non nil."
         (error (insert "\nInspector error for: " str))))
     (goto-char (point-min))))
 
+(defvar cider-inspector-looking-at-java-p nil)
+
 (defun cider-inspector-render* (elements)
   "Render ELEMENTS."
+  (setq cider-inspector-looking-at-java-p nil)
   (dolist (el elements)
     (cider-inspector-render-el* el)))
 
+(defconst cider--inspector-java-headers
+  '("--- Interfaces:" "--- Constructors:" "--- Fields:" "--- Methods:" "--- 
Imports:"))
+
 (defun cider-inspector-render-el* (el)
   "Render EL."
-  (cond ((symbolp el) (insert (symbol-name el)))
-        ((stringp el) (insert (propertize el 'font-lock-face 
'font-lock-keyword-face)))
-        ((and (consp el) (eq (car el) :newline))
-         (insert "\n"))
-        ((and (consp el) (eq (car el) :value))
-         (cider-inspector-render-value (cadr el) (cl-caddr el)))
-        (t (message "Unrecognized inspector object: %s" el))))
+  (let ((header-p (or (member el cider--inspector-java-headers)
+                      (and (stringp el)
+                           (string-prefix-p "--- " el)))))
+    ;; Headers reset the Java syntax coloring:
+    (when header-p
+      (setq cider-inspector-looking-at-java-p nil))
+
+    (cond ((symbolp el) (insert (symbol-name el)))
+          ((stringp el) (insert (if cider-inspector-looking-at-java-p
+                                    (cider-font-lock-as 'java-mode el)
+                                  (propertize el 'font-lock-face (if header-p
+                                                                     
'font-lock-comment-face
+                                                                   
'font-lock-keyword-face)))))
+          ((and (consp el) (eq (car el) :newline))
+           (insert "\n"))
+          ((and (consp el) (eq (car el) :value))
+           (cider-inspector-render-value (cadr el) (cl-caddr el)))
+          (t (message "Unrecognized inspector object: %s" el))))
+
+  ;; Java-related headers indicate that the next elements to be rendered
+  ;; should be syntax-colored as Java:
+  (when (member el cider--inspector-java-headers)
+    (setq cider-inspector-looking-at-java-p t)))
 
 (defun cider-inspector-render-value (value idx)
   "Render VALUE at IDX."
diff --git a/test/cider-inspector-tests.el b/test/cider-inspector-tests.el
new file mode 100644
index 0000000000..d8bbd4f2a2
--- /dev/null
+++ b/test/cider-inspector-tests.el
@@ -0,0 +1,373 @@
+;;; cider-inspectors-tests.el  -*- lexical-binding: t; -*-
+
+;; Copyright © 2012-2023 Bozhidar Batsov
+
+;; Author: Bozhidar Batsov <bozhidar@batsov.dev>
+
+;; This file is NOT part of GNU Emacs.
+
+;; 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 the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see `http://www.gnu.org/licenses/'.
+
+;;; Commentary:
+
+;; This file is part of CIDER
+
+;;; Code:
+
+(require 'buttercup)
+(require 'cider-inspector)
+
+;; Please, for each `describe', ensure there's an `it' block, so that its 
execution is visible in CI.
+
+;; A real-world example of a value that can be passed to 
`cider-inspector-render*':
+(defvar cider-inpector-tests--example-elements
+  '("Class" ": "
+    (:value "java.lang.Class" 0)
+    (:newline)
+    (:newline)
+    "--- Interfaces:"
+    (:newline)
+    "  "
+    (:value "clojure.lang.Counted" 1)
+    (:newline)
+    "  "
+    (:value "clojure.lang.IPersistentList" 2)
+    (:newline)
+    "  "
+    (:value "clojure.lang.IReduce" 3)
+    (:newline)
+    "  "
+    (:value "java.util.List" 4)
+    (:newline)
+    (:newline)
+    "--- Constructors:"
+    (:newline)
+    "  "
+    (:value "public clojure.lang.PersistentList(java.lang.Object)" 5)
+    (:newline)
+    (:newline)
+    "--- Fields:"
+    (:newline)
+    "  "
+    (:value "public static final clojure.lang.PersistentList$EmptyList 
clojure.lang.PersistentList.EMPTY" 6)
+    (:newline)
+    "  "
+    (:value "public static clojure.lang.IFn 
clojure.lang.PersistentList.creator" 7)
+    (:newline)
+    (:newline)
+    "--- Methods:"
+    (:newline)
+    "  "
+    (:value "public boolean clojure.lang.ASeq.add(java.lang.Object)" 8)
+    (:newline)
+    "  "
+    (:value "public void clojure.lang.ASeq.add(int,java.lang.Object)" 9)
+    (:newline)
+    "  "
+    (:value "public boolean 
clojure.lang.ASeq.addAll(int,java.util.Collection)" 10)
+    (:newline)
+    "  "
+    (:value "public boolean clojure.lang.ASeq.addAll(java.util.Collection)" 11)
+    (:newline)
+    "  "
+    (:value "public void clojure.lang.ASeq.clear()" 12)
+    (:newline)
+    "  "
+    (:value "public clojure.lang.IPersistentCollection 
clojure.lang.PersistentList.cons(java.lang.Object)" 13)
+    (:newline)
+    "  "
+    (:value "public clojure.lang.ISeq 
clojure.lang.PersistentList.cons(java.lang.Object)" 14)
+    (:newline)
+    "  "
+    (:value "public clojure.lang.PersistentList 
clojure.lang.PersistentList.cons(java.lang.Object)" 15)
+    (:newline)
+    "  "
+    (:value "public boolean clojure.lang.ASeq.contains(java.lang.Object)" 16)
+    (:newline)
+    "  "
+    (:value "public boolean 
clojure.lang.ASeq.containsAll(java.util.Collection)" 17)
+    (:newline)
+    "  "
+    (:value "public int clojure.lang.PersistentList.count()" 18)
+    (:newline)
+    "  "
+    (:value "public static clojure.lang.IPersistentList 
clojure.lang.PersistentList.create(java.util.List)" 19)
+    (:newline)
+    "  "
+    (:value "public clojure.lang.IPersistentCollection 
clojure.lang.PersistentList.empty()" 20)
+    (:newline)
+    "  "
+    (:value "public boolean clojure.lang.ASeq.equals(java.lang.Object)" 21)
+    (:newline)
+    "  "
+    (:value "public boolean clojure.lang.ASeq.equiv(java.lang.Object)" 22)
+    (:newline)
+    "  "
+    (:value "public java.lang.Object clojure.lang.PersistentList.first()" 23)
+    (:newline)
+    "  "
+    (:value "public default void 
java.lang.Iterable.forEach(java.util.function.Consumer)" 24)
+    (:newline)
+    "  "
+    (:value "public java.lang.Object clojure.lang.ASeq.get(int)" 25)
+    (:newline)
+    "  "
+    (:value "public final native java.lang.Class java.lang.Object.getClass()" 
26)
+    (:newline)
+    "  "
+    (:value "public int clojure.lang.ASeq.hashCode()" 27)
+    (:newline)
+    "  "
+    (:value "public int clojure.lang.ASeq.hasheq()" 28)
+    (:newline)
+    "  "
+    (:value "public int clojure.lang.ASeq.indexOf(java.lang.Object)" 29)
+    (:newline)
+    "  "
+    (:value "public boolean clojure.lang.ASeq.isEmpty()" 30)
+    (:newline)
+    "  "
+    (:value "public java.util.Iterator clojure.lang.ASeq.iterator()" 31)
+    (:newline)
+    "  "
+    (:value "public int clojure.lang.ASeq.lastIndexOf(java.lang.Object)" 32)
+    (:newline)
+    "  "
+    (:value "public java.util.ListIterator clojure.lang.ASeq.listIterator()" 
33)
+    (:newline)
+    "  "
+    (:value "public java.util.ListIterator 
clojure.lang.ASeq.listIterator(int)" 34)
+    (:newline)
+    "  "
+    (:value "public final clojure.lang.IPersistentMap clojure.lang.Obj.meta()" 
35)
+    (:newline)
+    "  "
+    (:value "public clojure.lang.ISeq clojure.lang.ASeq.more()" 36)
+    (:newline)
+    "  "
+    (:value "public clojure.lang.ISeq clojure.lang.PersistentList.next()" 37)
+    (:newline)
+    "  "
+    (:value "public final native void java.lang.Object.notify()" 38)
+    (:newline)
+    "  "
+    (:value "public final native void java.lang.Object.notifyAll()" 39)
+    (:newline)
+    "  "
+    (:value "public default java.util.stream.Stream 
java.util.Collection.parallelStream()" 40)
+    (:newline)
+    "  "
+    (:value "public java.lang.Object clojure.lang.PersistentList.peek()" 41)
+    (:newline)
+    "  "
+    (:value "public clojure.lang.IPersistentList 
clojure.lang.PersistentList.pop()" 42)
+    (:newline)
+    "  "
+    (:value "public clojure.lang.IPersistentStack 
clojure.lang.PersistentList.pop()" 43)
+    (:newline)
+    "  "
+    (:value "public java.lang.Object 
clojure.lang.PersistentList.reduce(clojure.lang.IFn)" 44)
+    (:newline)
+    "  "
+    (:value "public java.lang.Object 
clojure.lang.PersistentList.reduce(clojure.lang.IFn,java.lang.Object)" 45)
+    (:newline)
+    "  "
+    (:value "public boolean clojure.lang.ASeq.remove(java.lang.Object)" 46)
+    (:newline)
+    "  "
+    (:value "public java.lang.Object clojure.lang.ASeq.remove(int)" 47)
+    (:newline)
+    "  "
+    (:value "public boolean clojure.lang.ASeq.removeAll(java.util.Collection)" 
48)
+    (:newline)
+    "  "
+    (:value "public default boolean 
java.util.Collection.removeIf(java.util.function.Predicate)" 49)
+    (:newline)
+    "  "
+    (:value "public default void 
java.util.List.replaceAll(java.util.function.UnaryOperator)" 50)
+    (:newline)
+    "  "
+    (:value "public boolean clojure.lang.ASeq.retainAll(java.util.Collection)" 
51)
+    (:newline)
+    "  "
+    (:value "public final clojure.lang.ISeq clojure.lang.ASeq.seq()" 52)
+    (:newline)
+    "  "
+    (:value "public java.lang.Object 
clojure.lang.ASeq.set(int,java.lang.Object)" 53)
+    (:newline)
+    "  "
+    (:value "public int clojure.lang.ASeq.size()" 54)
+    (:newline)
+    "  "
+    (:value "public default void java.util.List.sort(java.util.Comparator)" 55)
+    (:newline)
+    "  "
+    (:value "public default java.util.Spliterator 
java.util.List.spliterator()" 56)
+    (:newline)
+    "  "
+    (:value "public default java.util.stream.Stream 
java.util.Collection.stream()" 57)
+    (:newline)
+    "  "
+    (:value "public java.util.List clojure.lang.ASeq.subList(int,int)" 58)
+    (:newline)
+    "  "
+    (:value "public default java.lang.Object[] 
java.util.Collection.toArray(java.util.function.IntFunction)" 59)
+    (:newline)
+    "  "
+    (:value "public java.lang.Object[] clojure.lang.ASeq.toArray()" 60)
+    (:newline)
+    "  "
+    (:value "public java.lang.Object[] 
clojure.lang.ASeq.toArray(java.lang.Object[])" 61)
+    (:newline)
+    "  "
+    (:value "public java.lang.String clojure.lang.ASeq.toString()" 62)
+    (:newline)
+    "  "
+    (:value "public final native void java.lang.Object.wait(long) throws 
java.lang.InterruptedException" 63)
+    (:newline)
+    "  "
+    (:value "public final void java.lang.Object.wait() throws 
java.lang.InterruptedException" 64)
+    (:newline)
+    "  "
+    (:value "public final void java.lang.Object.wait(long,int) throws 
java.lang.InterruptedException" 65)
+    (:newline)
+    "  "
+    (:value "public clojure.lang.IObj 
clojure.lang.PersistentList.withMeta(clojure.lang.IPersistentMap)" 66)
+    (:newline)
+    "  "
+    (:value "public clojure.lang.Obj 
clojure.lang.PersistentList.withMeta(clojure.lang.IPersistentMap)" 67)
+    (:newline)
+    "  "
+    (:value "public clojure.lang.PersistentList 
clojure.lang.PersistentList.withMeta(clojure.lang.IPersistentMap)" 68)
+    (:newline)
+    (:newline)
+    "--- Datafy:"
+    (:newline)
+    "  "
+    (:value ":bases" 69)
+    " = "
+    (:value "#{ clojure.lang.IReduce clojure.lang.Counted clojure.lang.ASeq 
java.util.List clojure.lang.IPersistentList }" 70)
+    (:newline)
+    "  "
+    (:value ":flags" 71)
+    " = "
+    (:value "#{ :public }" 72)
+    (:newline)
+    "  "
+    (:value ":members" 73)
+    " = "
+    (:value "{ EMPTY [ { :name EMPTY, :type 
clojure.lang.PersistentList$EmptyList, :declaring-class 
clojure.lang.PersistentList, :flags #{ :public :static :final } } ], _count [ { 
:name _count, :type int, :declaring-class clojure.lang.PersistentList, :flags 
#{ :private :final } } ], _first [ { :name _first, :type java.lang.Object, 
:declaring-class clojure.lang.PersistentList, :flags #{ :private :final } } ], 
_rest [ { :name _rest, :type clojure.lang.IPersistentList, :declaring-class 
cloj [...]
+    (:newline)
+    "  "
+    (:value ":name" 75)
+    " = "
+    (:value "clojure.lang.PersistentList" 76)
+    (:newline)
+    (:newline)
+    "--- Path:"
+    (:newline)
+    "  " "class"))
+
+(describe "cider-inspector-render*"
+  (it "Produces a well-known string without errors"
+    (expect
+     (with-temp-buffer
+       (cider-inspector-render* cider-inpector-tests--example-elements)
+       (buffer-string))
+     :to-equal "Class: java.lang.Class
+
+--- Interfaces:
+  clojure.lang.Counted
+  clojure.lang.IPersistentList
+  clojure.lang.IReduce
+  java.util.List
+
+--- Constructors:
+  public clojure.lang.PersistentList(java.lang.Object)
+
+--- Fields:
+  public static final clojure.lang.PersistentList$EmptyList 
clojure.lang.PersistentList.EMPTY
+  public static clojure.lang.IFn clojure.lang.PersistentList.creator
+
+--- Methods:
+  public boolean clojure.lang.ASeq.add(java.lang.Object)
+  public void clojure.lang.ASeq.add(int,java.lang.Object)
+  public boolean clojure.lang.ASeq.addAll(int,java.util.Collection)
+  public boolean clojure.lang.ASeq.addAll(java.util.Collection)
+  public void clojure.lang.ASeq.clear()
+  public clojure.lang.IPersistentCollection 
clojure.lang.PersistentList.cons(java.lang.Object)
+  public clojure.lang.ISeq clojure.lang.PersistentList.cons(java.lang.Object)
+  public clojure.lang.PersistentList 
clojure.lang.PersistentList.cons(java.lang.Object)
+  public boolean clojure.lang.ASeq.contains(java.lang.Object)
+  public boolean clojure.lang.ASeq.containsAll(java.util.Collection)
+  public int clojure.lang.PersistentList.count()
+  public static clojure.lang.IPersistentList 
clojure.lang.PersistentList.create(java.util.List)
+  public clojure.lang.IPersistentCollection clojure.lang.PersistentList.empty()
+  public boolean clojure.lang.ASeq.equals(java.lang.Object)
+  public boolean clojure.lang.ASeq.equiv(java.lang.Object)
+  public java.lang.Object clojure.lang.PersistentList.first()
+  public default void java.lang.Iterable.forEach(java.util.function.Consumer)
+  public java.lang.Object clojure.lang.ASeq.get(int)
+  public final native java.lang.Class java.lang.Object.getClass()
+  public int clojure.lang.ASeq.hashCode()
+  public int clojure.lang.ASeq.hasheq()
+  public int clojure.lang.ASeq.indexOf(java.lang.Object)
+  public boolean clojure.lang.ASeq.isEmpty()
+  public java.util.Iterator clojure.lang.ASeq.iterator()
+  public int clojure.lang.ASeq.lastIndexOf(java.lang.Object)
+  public java.util.ListIterator clojure.lang.ASeq.listIterator()
+  public java.util.ListIterator clojure.lang.ASeq.listIterator(int)
+  public final clojure.lang.IPersistentMap clojure.lang.Obj.meta()
+  public clojure.lang.ISeq clojure.lang.ASeq.more()
+  public clojure.lang.ISeq clojure.lang.PersistentList.next()
+  public final native void java.lang.Object.notify()
+  public final native void java.lang.Object.notifyAll()
+  public default java.util.stream.Stream java.util.Collection.parallelStream()
+  public java.lang.Object clojure.lang.PersistentList.peek()
+  public clojure.lang.IPersistentList clojure.lang.PersistentList.pop()
+  public clojure.lang.IPersistentStack clojure.lang.PersistentList.pop()
+  public java.lang.Object clojure.lang.PersistentList.reduce(clojure.lang.IFn)
+  public java.lang.Object 
clojure.lang.PersistentList.reduce(clojure.lang.IFn,java.lang.Object)
+  public boolean clojure.lang.ASeq.remove(java.lang.Object)
+  public java.lang.Object clojure.lang.ASeq.remove(int)
+  public boolean clojure.lang.ASeq.removeAll(java.util.Collection)
+  public default boolean 
java.util.Collection.removeIf(java.util.function.Predicate)
+  public default void 
java.util.List.replaceAll(java.util.function.UnaryOperator)
+  public boolean clojure.lang.ASeq.retainAll(java.util.Collection)
+  public final clojure.lang.ISeq clojure.lang.ASeq.seq()
+  public java.lang.Object clojure.lang.ASeq.set(int,java.lang.Object)
+  public int clojure.lang.ASeq.size()
+  public default void java.util.List.sort(java.util.Comparator)
+  public default java.util.Spliterator java.util.List.spliterator()
+  public default java.util.stream.Stream java.util.Collection.stream()
+  public java.util.List clojure.lang.ASeq.subList(int,int)
+  public default java.lang.Object[] 
java.util.Collection.toArray(java.util.function.IntFunction)
+  public java.lang.Object[] clojure.lang.ASeq.toArray()
+  public java.lang.Object[] clojure.lang.ASeq.toArray(java.lang.Object[])
+  public java.lang.String clojure.lang.ASeq.toString()
+  public final native void java.lang.Object.wait(long) throws 
java.lang.InterruptedException
+  public final void java.lang.Object.wait() throws 
java.lang.InterruptedException
+  public final void java.lang.Object.wait(long,int) throws 
java.lang.InterruptedException
+  public clojure.lang.IObj 
clojure.lang.PersistentList.withMeta(clojure.lang.IPersistentMap)
+  public clojure.lang.Obj 
clojure.lang.PersistentList.withMeta(clojure.lang.IPersistentMap)
+  public clojure.lang.PersistentList 
clojure.lang.PersistentList.withMeta(clojure.lang.IPersistentMap)
+
+--- Datafy:
+  :bases = #{ clojure.lang.IReduce clojure.lang.Counted clojure.lang.ASeq 
java.util.List clojure.lang.IPersistentList }
+  :flags = #{ :public }
+  :members = { EMPTY [ { :name EMPTY, :type 
clojure.lang.PersistentList$EmptyList, :declaring-class 
clojure.lang.PersistentList, :flags #{ :public :static :final } } ], _count [ { 
:name _count, :type int, :declaring-class clojure.lang.PersistentList, :flags 
#{ :private :final } } ], _first [ { :name _first, :type java.lang.Object, 
:declaring-class clojure.lang.PersistentList, :flags #{ :private :final } } ], 
_rest [ { :name _rest, :type clojure.lang.IPersistentList, :declaring-class 
cloj [...]
+  :name = clojure.lang.PersistentList
+
+--- Path:
+  class")))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]