GitHub - ertugrulcetin/code-bubble · GitHub
/" data-turbo-transient="true" />
Skip to content
Search or jump to...
Search code, repositories, users, issues, pull requests...
-->
Search
Clear
Search syntax tips
Provide feedback
--><br>We read every piece of feedback, and take your input very seriously.
Include my email address so I can be contacted
Cancel
Submit feedback
Saved searches
Use saved searches to filter your results more quickly
-->
Name
Query
To see all available qualifiers, see our documentation.
Cancel
Create saved search
Sign in
/;ref_cta:Sign up;ref_loc:header logged out"}"<br>Sign up
Appearance settings
Resetting focus
You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.
Dismiss alert
{{ message }}
ertugrulcetin
code-bubble
Public
Notifications<br>You must be signed in to change notification settings
Fork
Star
master
BranchesTags
Go to file
CodeOpen more actions menu
Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit
History<br>11 Commits<br>11 Commits
dev
dev
src/code_bubble
src/code_bubble
.gitignore
.gitignore
README.md
README.md
code-bubble-clj.png
code-bubble-clj.png
deps.edn
deps.edn
pom.xml
pom.xml
project.clj
project.clj
View all files
Repository files navigation
code-bubble
Disclaimer — this project is AI-generated.
A Clojure dev-time UI inspired by<br>Code Bubbles: open vars as draggable<br>bubbles on a shared canvas, click cross-references to fan out the call graph,<br>auto-arrange when it gets busy.
Install
Leiningen (project.clj)
:profiles {:dev {:dependencies [[io.github.ertugrulcetin/code-bubble "0.2.1"]]}}
tools.deps (deps.edn)
{:aliases<br>{:bubbles<br>{:extra-deps {io.github.ertugrulcetin/code-bubble<br>{:mvn/version "0.2.1"}}}}}
clj -A:bubbles -M -r to enter a REPL with code-bubble available.
Quickstart
(require '[code-bubble.core :as bubbles])
(bubbles/show!) ; open the canvas<br>(bubbles/show! 'clojure.string/blank?) ; + add a bubble
Hover any identifier in a bubble — the cursor switches to HAND on navigable<br>references; click to open them.
Pre-load libraries on startup
Drop a Maven coord onto the classpath and into the namespace browser in one<br>call. Two shapes:
;; Already at the REPL:<br>(bubbles/load-lib! '[dev.weavejester/medley "1.10.0"])
;; Or as part of opening the window:<br>(bubbles/show-with-libs! '[[dev.weavejester/medley "1.10.0"]<br>[org.clj-commons/humanize "1.1"]])
This (a) resolves the lib via tools.deps, (b) eagerly requires every<br>namespace it ships, (c) refreshes the browser so they appear in the left<br>column.
If the lib is already on the classpath (e.g. you put it in -Sdeps),<br>this works in any context — no interactive REPL needed. If it's not yet<br>loaded, load-lib! falls back to clojure.repl.deps/add-libs which<br>requires Clojure 1.12+ and an interactive REPL.
A complete shell one-liner:
clj -Sdeps '{:deps {io.github.ertugrulcetin/code-bubble {:mvn/version "0.2.1"}<br>dev.weavejester/medley {:mvn/version "1.10.0"}}}' \<br>-M -e '(require (quote [code-bubble.core :as b])) (b/show-with-libs! (quote [[dev.weavejester/medley "1.10.0"]]))'
Navigating
Gesture<br>Effect
Click-drag (within 50 ms)<br>Pan canvas
Click-and-hold then drag on a bubble<br>Move bubble / select text / resize
Click empty canvas<br>Drop focus from any bubble
Wheel over empty canvas / unfocused bubble<br>Pan
Wheel after clicking into a bubble's body<br>Scroll that bubble
Shift + wheel<br>Pan horizontally
Two-finger pinch (macOS)<br>Zoom (cursor-anchored)
Cursor is the only affordance for navigable refs — no underline. Pinch<br>needs Apple's com.apple.eawt.event classes (most modern macOS JDKs ship<br>them).
Keyboard
Shortcut<br>Action
⌘K<br>Open Function…
⌘T<br>New tab
⌘W<br>Hide window
⌘⇧K<br>Clear active workspace
⌘⇧A<br>Auto-arrange (Sugiyama tree layout)
⌘L<br>Toggle connectors
⌘J<br>Toggle browser
⌘= ⌘- ⌘0<br>Zoom in / out / reset
⌘,<br>Preferences…
⌘ on macOS, Ctrl elsewhere.
Workspaces
Each tab is an independent canvas — its own bubbles, edges, zoom, focus.<br>Double-click a tab title to rename. Closing the last tab spawns a fresh<br>one.
Namespace browser
Left sidebar (⌘J to toggle). Two filterable lists side-by-side: every<br>loaded namespace, then every var in the selected namespace. Filters do<br>fuzzy subsequence matching with score-based ranking. Double-click a var<br>to open it as a bubble in the active workspace.
Anchored connectors
Click a navigable identifier: a connector arrow is drawn from the line<br>containing the click (highlighted in soft amber) straight to the new<br>child bubble. The new bubble is positioned at the same y as that row —<br>arrows stay short and roughly horizontal.
Public API
code-bubble.core/…:
fn<br>what
show! [] / [sym]<br>open window, optionally with a bubble
show-with-libs! [coords]<br>open window after loading libs
load-lib! [coord] / [lib version]<br>load a lib + refresh...