Skip to content

Commit a42fd57

Browse files
mkphilippamarkovics
authored andcommitted
Features listing for Clojure Mode page
* Side-by-side layout, show features along with bindings * Mobile layout * Use correct code font for results * Fix editor margin on mobile * Make clojure-mode instructions more compact * Update features design, add use it section * Add max-height to editor * Add demo editor header with link to sci * Show keybindings before use it * Monospace commands * Surping -> Slurping * Make modifier key platform dependent * Emoji spacing * Table headings & row hovers * Add spacing for keybindings * Simplify editor creation * Restructure clojure-mode demo to be in own folder * Render Twitter emojis on Linux * Render Ctrl platform-specific * Adjust editor max-height * Mobile improvements * Don't init demo editor multiple times Co-authored-by: Philipp Markovics <[email protected]> Co-authored-by: Philipp Markovics <[email protected]> Co-authored-by: Philipp Markovics <[email protected]> Co-authored-by: Philipp Markovics <[email protected]> Co-authored-by: Philipp Markovics <[email protected]> Co-authored-by: Philipp Markovics <[email protected]> Co-authored-by: Philipp Markovics <[email protected]> Co-authored-by: Philipp Markovics <[email protected]> Co-authored-by: Philipp Markovics <[email protected]> Co-authored-by: Philipp Markovics <[email protected]> Co-authored-by: Philipp Markovics <[email protected]> Co-authored-by: Philipp Markovics <[email protected]> Co-authored-by: Philipp Markovics <[email protected]> Co-authored-by: Philipp Markovics <[email protected]> Co-authored-by: Philipp Markovics <[email protected]> Co-authored-by: Philipp Markovics <[email protected]> Co-authored-by: Philipp Markovics <[email protected]>
1 parent 9401294 commit a42fd57

26 files changed

+245
-96
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
.shadow-cljs
22
.idea
3+
.calva
4+
.clj-kondo
5+
.lsp
36
public/js
47
node_modules
58
public/test
6-
*.iml
9+
*.iml

demo/deps.edn

Whitespace-only changes.

src/demo/nextjournal/clojure_mode/demo.cljs renamed to demo/src/nextjournal/clojure_mode/demo.cljs

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -58,30 +58,34 @@
5858
(.of view/keymap cm-clj/complete-keymap)
5959
(.of view/keymap historyKeymap)])
6060

61-
(defonce !view (atom nil))
6261

63-
(defn editor [source]
64-
(r/with-let [last-result (r/atom (sci/eval-string source))
62+
(defn editor [source {:keys [eval?]}]
63+
(r/with-let [!view (r/atom nil)
64+
last-result (when eval? (r/atom (sci/eval-string source)))
6565
mount! (fn [el]
6666
(when el
6767
(reset! !view (new EditorView
6868
(j/obj :state
6969
(test-utils/make-state
70-
#js[extensions
71-
(sci/extension {:modifier "Alt"
72-
:on-result (partial reset! last-result)})] source)
70+
(cond-> #js [extensions]
71+
eval? (.concat #js [(sci/extension {:modifier "Alt"
72+
:on-result (partial reset! last-result)})]))
73+
source)
7374
:parent el)))))]
7475
[:div
75-
[:div {:class "mt-4 rounded-md mb-0 text-sm monospace overflow-auto relative shadow-sm bg-white"
76-
:ref mount!}]
77-
[:div.mt-3.mv-4.pl-6 {:style {:white-space "pre-wrap" :font-family "monospace"}}
78-
(prn-str @last-result)]]
76+
[:div {:class "rounded-md mb-0 text-sm monospace overflow-auto relative border shadow-lg bg-white"
77+
:ref mount!
78+
:style {:max-height 410}}]
79+
(when eval?
80+
[:div.mt-3.mv-4.pl-6 {:style {:white-space "pre-wrap" :font-family "var(--code-font)"}}
81+
(prn-str @last-result)])]
7982
(finally
80-
(j/call @!view :destroy))))
83+
(j/call @!view :destroy))))
84+
8185

8286
(defn samples []
8387
(into [:<>]
84-
(for [source ["(comment ;; try evaluating those with alt-enter
88+
(for [source ["(comment
8589
(fizz-buzz 1)
8690
(fizz-buzz 3)
8791
(fizz-buzz 5)
@@ -95,7 +99,7 @@
9599
3 \"fizz\"
96100
5 \"buzz\"
97101
n))"]]
98-
[editor source])))
102+
[editor source {:eval? true}])))
99103

100104
(defn tag [tag & s]
101105
(let [[opts s] (if (map? (first s)) [(first s) (rest s)] [nil s])]
@@ -104,6 +108,9 @@
104108
(defn mac? []
105109
(some? (re-find #"Mac" js/navigator.platform)))
106110

111+
(defn linux? []
112+
(some? (re-find #"(Linux)|(X11)" js/navigator.userAgent)))
113+
107114
(defn key-mapping []
108115
(cond-> {"ArrowUp" ""
109116
"ArrowDown" ""
@@ -120,52 +127,50 @@
120127
(defn render-key [key]
121128
(let [keys (into [] (map #(get ((memoize key-mapping)) % %) (str/split key #"-")))]
122129
(tag :span
123-
(str/join (tag :span "+") (map (partial tag :kdb {:class "bg-gray monospace m-1" :style "border-radius: 5px; padding: 1px 4px; border: 1px solid black;"}) keys)))))
130+
(str/join (tag :span " + ") (map (partial tag :kdb {:class "kbd"}) keys)))))
124131

125132
(defn ^:dev/after-load render []
126133
(rdom/render [samples] (js/document.getElementById "editor"))
134+
(.. (js/document.querySelectorAll "[clojure-mode]")
135+
(forEach #(when-not (.-firstElementChild %)
136+
(rdom/render [editor (str/trim (.-innerHTML %))] %))))
137+
138+
(let [mapping (key-mapping)]
139+
(.. (js/document.querySelectorAll ".mod,.alt,.ctrl")
140+
(forEach #(when-let [k (get mapping (.-innerHTML %))]
141+
(set! (.-innerHTML %) k)))))
142+
127143
(j/assoc! (js/document.getElementById "docs")
128144
:innerHTML
129145
(tag :div
130-
(tag :h3 {:class "m-3" } "Keybindings")
146+
(tag :h2 {:class "text-center text-3xl font-bold mt-0 mb-12"}
147+
(tag :a {:class "near-black" :href "#keybindings"} "🎹 Keybindings"))
131148
(tag :table {:cellpadding 0 :class "w-full text-sm"}
132149
(tag :tr
133150
{:class "border-t even:bg-gray-100"}
134-
(tag :td {:class "px-3 py-1 align-top text-sm"} "Command")
135-
(tag :td {:class "px-3 py-1 align-top text-sm"} "Keybinding")
136-
(tag :td {:class "px-3 py-1 align-top text-sm"} "Alternate Binding")
137-
(tag :td {:class "px-3 py-1 align-top text-sm"} "Description"))
151+
(tag :th {:class "px-3 py-1 align-top text-left text-xs uppercase font-normal black-50"} "Command")
152+
(tag :th {:class "px-3 py-1 align-top text-left text-xs uppercase font-normal black-50"} "Keybinding")
153+
(tag :th {:class "px-3 py-1 align-top text-left text-xs uppercase font-normal black-50"} "Alternate Binding")
154+
(tag :th {:class "px-3 py-1 align-top text-left text-xs uppercase font-normal black-50"} "Description"))
138155
(->> keymap/paredit-keymap*
139156
(merge (sci/keymap* "Alt"))
140157
(sort-by first)
141158
(reduce (fn [out [command [{:keys [key shift doc]} & [{alternate-key :key}]]]]
142159
(str out
143160
(tag :tr
144-
{:class "border-t even:bg-gray-100"}
145-
(tag :td {:class "px-3 py-1 align-top"} (tag :b (name command)))
161+
{:class "border-t hover:bg-gray-100"}
162+
(tag :td {:class "px-3 py-1 align-top monospace"} (tag :b (name command)))
146163
(tag :td {:class "px-3 py-1 align-top text-sm"} (render-key key))
147164
(tag :td {:class "px-3 py-1 align-top text-sm"} (some-> alternate-key render-key))
148165
(tag :td {:class "px-3 py-1 align-top"} doc))
149166
(when shift
150167
(tag :tr
151-
{:class "border-t even:bg-gray-100"}
168+
{:class "border-t hover:bg-gray-100"}
152169
(tag :td {:class "px-3 py-1 align-top"} (tag :b (name shift)))
153170
(tag :td {:class "px-3 py-1 align-top text-sm"}
154171
(render-key (str "Shift-" key)))
155172
(tag :td {:class "px-3 py-1 align-top text-sm"})
156-
(tag :td {:class "px-3 py-1 align-top"} ""))))) ""))
157-
"</table>"))))
158-
159-
160-
(comment
161-
(def state (.-state @!view))
162-
163-
(def doc (.-doc state))
173+
(tag :td {:class "px-3 py-1 align-top"} ""))))) "")))))
164174

165-
(def iter (.iter doc))
166-
(def n (.next iter))
167-
(.-lineBreak n)
168-
(let [s "#(a )"
169-
state (test-utils/make-state default-extensions s)
170-
tree (n/tree state)]
171-
))
175+
(when (linux?)
176+
(js/twemoji.parse (.-body js/document))))

deps.edn

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
{:paths ["src/main"
2-
"src/test"]
3-
:deps {applied-science/js-interop {:mvn/version "0.2.5"}
4-
org.clojure/clojurescript {:mvn/version "1.10.773"}
5-
thheller/shadow-cljs {:mvn/version "2.11.1"}}
1+
{:deps {applied-science/js-interop {:mvn/version "0.2.5"}
2+
org.clojure/clojurescript {:mvn/version "1.10.773"}}
63
:aliases
7-
{:demo {:extra-deps {borkdude/sci {:mvn/version "0.2.0"}
8-
reagent/reagent {:mvn/version "0.9.1"}}
9-
:extra-paths ["src/demo"]}}}
4+
{:dev {:extra-paths ["test"]
5+
:extra-deps {thheller/shadow-cljs {:mvn/version "2.11.11"}}}
6+
:demo {:extra-deps {borkdude/sci {:mvn/version "0.2.0"}
7+
reagent/reagent {:mvn/version "1.0.0"}}
8+
:extra-paths ["demo/src"]}}}

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
"lezer-tree": "^0.13.0",
77
"lezer-generator": "^0.13.0",
88
"platform": "1.3.5",
9-
"react": "16.13.0",
10-
"react-dom": "16.13.0",
11-
"shadow-cljs": "^2.10.17",
9+
"react": "17.0.1",
10+
"react-dom": "17.0.1",
11+
"shadow-cljs": "^2.11.11",
1212
"stacktrace-js": "^2.0.2",
1313
"w3c-keyname": "^2.2.4"
1414
},

public/index.html

Lines changed: 168 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,45 @@
66
<link href="https://cdn.nextjournal.com/data/QmW53nJSRrRao5FZ9sZ2pwQ4Gd4mK4nZcvhrATVdiabPkc?filename=tailwind-a4c8a6fe636b6d528505c30cb68526a024f446a7.css&content-type=text/css" rel="stylesheet">
77
<link href="https://cdn.nextjournal.com/data/QmSaHZCU6U2DeNohfW2PuXDHkayw7w21uvUWL5oEqVWKwH?filename=viewer-1c61aac61ffa4da89b828d538c5e4eff188e7b56.css&content-type=text/css" rel="stylesheet">
88
<link href="https://cdn.nextjournal.com/data/QmZZpjcdZDa8WT27QpcepDfqwuGik6Y3Ueyxaxs1Gqpk9w?filename=nextjournal-c81d440c5a7312046bbc5a2c3f2c5567d9ea9131.css&content-type=text/css" rel="stylesheet">
9+
<script src="https://twemoji.maxcdn.com/v/latest/twemoji.min.js" crossorigin="anonymous"></script>
910
<style>
1011
/* Use Fira Mono without having to clutter up the demo with a custom CM theme. */
1112
.cm-scroller { font-family: var(--code-font) !important; }
13+
.kbd {
14+
box-shadow: 0 2px 2px rgba(0,0,0,.1);
15+
background: white;
16+
border: 1px solid rgba(0,0,0,.15);
17+
border-radius: 3px;
18+
font-size: 0.75em;
19+
padding: 2px 5px;
20+
position: relative;
21+
top: -2px;
22+
font-family: var(--code-font);
23+
text-transform: uppercase;
24+
}
25+
img.emoji {
26+
height: 1em;
27+
width: 1em;
28+
margin: 0 .05em 0 .1em;
29+
vertical-align: -0.1em;
30+
display: inline-block;
31+
}
32+
.cta img.emoji {
33+
margin-right: 0.3em;
34+
}
35+
@media (max-width: 800px) {
36+
.ctas {
37+
font-size: 1rem !important;
38+
}
39+
}
40+
@media (max-width: 500px) {
41+
.ctas {
42+
flex-direction: column;
43+
}
44+
.ctas .cta {
45+
margin-bottom: 0.5rem;
46+
}
47+
}
1248
</style>
1349
</head>
1450
<body>
@@ -17,28 +53,150 @@
1753
<div>
1854
<h1>Clojure/Script mode for <a href="https://codemirror.net/6/">CodeMirror 6</a></h1>
1955
<p>
20-
Enable a decent Clojure/Script editor experience in the browser.
21-
Implemented as a <a href="https://lezer.codemirror.net">lezer</a> grammar.
22-
Built by <a href="https://nextjournal.com">Nextjournal</a>.
56+
Enable a decent Clojure/Script editor experience in the browser.<br>
57+
Built for and by <a href="https://nextjournal.com">Nextjournal</a>.
2358
</p>
2459
<div class="ctas">
2560
<a href="https://github.com/nextjournal/clojure-mode" class="cta">
26-
 🐙 Clone on GitHub
61+
🐙 Clone on GitHub
2762
</a>
2863
<a href="https://nextjournal.com/try/clojure?cm6=1" class="cta">
2964
🤹‍♀️ Try in Nextjournal
3065
</a>
66+
<a href="#use-it" class="cta">
67+
📦 Use it
68+
</a>
3169
</div>
32-
3370
</div>
3471
</div>
3572
</div>
36-
<div class="bg-alt pb-12 px-6 pt-3">
37-
<div class="max-w-4xl mx-auto">
38-
<div id="editor"></div>
73+
<div class="bg-alt pb-12 px-6 pt-12 mt-6">
74+
<h2 id="try-it" class="mt-0 mb-12 text-center text-3xl font-bold">
75+
<a href="#try-it" class="near-black">🤹‍♀️ Try it for yourself</a>
76+
</h2>
77+
<div class="flex flex-col-reverse md:flex-row">
78+
<div class="md:w-1/2 flex-shrink-0 md:px-6 mt-12 md:mt-0">
79+
<h3 class="text-center sans-serif font-bold text-lg mt-0 mb-1">Try evaluating any of these forms with <span class="kbd alt font-normal">Alt</span> <span class="font-normal">+</span> <span class="kbd font-normal"></span> !</h3>
80+
<p class="sans-serif text-sm text-center mb-6 mt-0">
81+
In-browser eval is powered by <a href="https://github.com/borkdude/sci">Sci</a>.
82+
</p>
83+
<div id="editor"></div>
84+
</div>
85+
<div class="md:w-1/2 flex-shrink-0 md:px-6 sans-serif">
86+
<ul class="text-lg">
87+
<li class="pr-12 flex">
88+
<span class="mr-2">⚡️</span>
89+
<div class="flex-auto">
90+
<span class="font-bold">Lightning-fast</span> with <a href="https://lezer.codemirror.net">lezer incremental parsing</a><br>
91+
<span class="text-sm">
92+
Copy <a href="https://raw.githubusercontent.com/clojure/clojure/master/src/clj/clojure/core.clj" target="_blank"><code>clojure/core.clj</code></a> into 👈 <span class="ml-1">to try!</span>
93+
</span>
94+
</div>
95+
</li>
96+
<li class="mt-4 flex">
97+
<span class="mr-2">🥤</span>
98+
<div class="flex-auto">
99+
<span class="font-bold">Slurping & 🤮 Barfing</span>
100+
<table class="w-full md:max-w-sm text-sm">
101+
<tbody>
102+
<tr class="align-top">
103+
<td class="py-1">forward</td>
104+
<td class="py-1 text-right">
105+
<span class="kbd ctrl">Ctrl</span> + <span class="kbd"></span> / <span class="kbd"></span>
106+
</td>
107+
<td class="py-1 text-right">
108+
<span class="mx-1">or</span> <span class="kbd mod">Mod</span> + <span class="kbd"></span> + <span class="kbd">j</span> / <span class="kbd">k</span>
109+
</td>
110+
</tr>
111+
<tr class="border-t">
112+
<td class="py-1 pr-12">backward</td>
113+
<td class="py-1 text-right">
114+
<span class="kbd ctrl">Ctrl</span> + <span class="kbd alt">Alt</span> + <span class="kbd"></span> / <span class="kbd"></span>
115+
</td>
116+
<td></td>
117+
</tr>
118+
</tbody>
119+
</table>
120+
</div>
121+
</li>
122+
<li class="mt-4 flex">
123+
<span class="mr-2">💗</span>
124+
<div class="flex-auto">
125+
<span class="font-bold">Semantic Selections</span>
126+
<table class="w-full md:max-w-sm text-sm">
127+
<tbody>
128+
<tr>
129+
<td class="py-1" style="width: 150px;">Expand / Contract</td>
130+
<td class="py-1 text-right" style="width: 125px;">
131+
<span class="kbd alt">Alt</span> + <span class="kbd"></span> / <span class="kbd"></span>
132+
</td>
133+
<td class="py-1 text-right">
134+
<span class="mx-1">or</span> <span class="kbd mod">Mod</span> + <span class="kbd">1</span> / <span class="kbd">2</span>
135+
</td>
136+
</tr>
137+
</tbody>
138+
</table>
139+
</div>
140+
</li>
141+
<li class="mt-4 flex">
142+
<span class="mr-2">🧙</span>
143+
<div class="flex-auto">
144+
<span class="font-bold">Evaluation</span>
145+
<table class="w-full md:max-w-sm text-sm">
146+
<tbody>
147+
<tr>
148+
<td class="py-1 pr-12">
149+
At Cursor
150+
</td>
151+
<td class="py-1 text-right">
152+
<span class="kbd alt">Alt</span> + <span class="kbd"></span>
153+
</td>
154+
</tr>
155+
<tr class="border-t">
156+
<td class="py-1 pr-12">
157+
Top-level form
158+
</td>
159+
<td class="py-1 text-right">
160+
<span class="kbd alt">Alt</span> + <span class="kbd"></span> + <span class="kbd"></span>
161+
</td>
162+
</tr>
163+
<tr class="border-t">
164+
<td class="py-1 pr-12">
165+
Cell
166+
</td>
167+
<td class="py-1 text-right">
168+
<span class="kbd mod">Mod</span> + <span class="kbd"></span>
169+
</td>
170+
</tr>
171+
</tbody>
172+
</table>
173+
</div>
174+
</li>
175+
<li class="mt-4 flex">
176+
<span class="mr-2">🧹</span>
177+
<div class="flex-auto">
178+
<span class="font-bold">Autoformatting</span>
179+
<p class="mt-1 text-sm">
180+
following <a href="https://tonsky.me/blog/clojurefmt/">Tonsky’s Better Clojure Formatting</a>
181+
</p>
182+
</div>
183+
</li>
184+
</ul>
185+
</div>
39186
</div>
40-
<div class="max-w-4xl mx-auto">
41-
<div id="docs" class="border-t-0 overflow-auto text-md p-0 m-0 mt-4 sans-serif"></div>
187+
</div>
188+
<div class="max-w-4xl mx-auto py-12 px-6">
189+
<div id="docs" class="border-t-0 overflow-auto text-md p-0 m-0 sans-serif"></div>
190+
</div>
191+
<div class="bg-alt py-12 px-6">
192+
<div id="use-it" class="mx-auto max-w-4xl">
193+
<h2 class="mt-0 mb-8 text-3xl font-bold text-center">
194+
<a href="#use-it" class="near-black">📦 Use it in your project</a>
195+
</h2>
196+
<pre clojure-mode="true" class="max-w-4xl mx-auto">
197+
{:deps {nextjournal.clojure-mode {:git/url "https://github.com/nextjournal/clojure-mode"
198+
:sha "SHA"}}}
199+
</pre>
42200
</div>
43201
</div>
44202
<div class="border-t-2 px-6">

shadow-cljs.edn

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{:deps true
1+
{:deps {:aliases [:dev :demo]}
22
:dev-http {8002 "public"
33
8001 "public/test"}
44
:nrepl {:port 9000}
File renamed without changes.

0 commit comments

Comments
 (0)