From 30892ef85f4b56c44713e8e0a91f008f77eb1461 Mon Sep 17 00:00:00 2001 From: Timo Kramer Date: Wed, 8 Apr 2026 12:42:20 +0200 Subject: [PATCH 1/6] docs: improve badges and versioning docs --- README.md | 20 ++++++++++++-------- build.clj | 2 +- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 1e9a0aa..14d1511 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # charm.clj -![Status](https://img.shields.io/badge/status-alpha-orange) +![Status](https://img.shields.io/badge/status-beta-blue) [![Clojars Project](https://img.shields.io/clojars/v/de.timokramer/charm.clj.svg)](https://clojars.org/de.timokramer/charm.clj) +[![GitHub tag](https://img.shields.io/github/v/tag/TimoKramer/charm.clj?label=git%20tag)](https://github.com/TimoKramer/charm.clj/tags) A Clojure TUI (Terminal User Interface) library inspired by [Bubble Tea](https://github.com/charmbracelet/bubbletea). @@ -10,8 +11,8 @@ on the JVM, as a native-image binary or on [babashka](https://babashka.org). ## Status -This library is vibecoded and very early. It works for the examples but please let me know if you encounter any -issues. I am planning to use it for something more sophisticated. Please expect breaking changes. +This library is in beta. The API is stabilizing but breaking changes may still occur. Please let me know if you +encounter any issues. ## Features @@ -39,15 +40,18 @@ issues. I am planning to use it for something more sophisticated. Please expect ## Installation -Add to your `deps.edn`: +Add to your `deps.edn`. Click the badges to find the latest version and git tag: + +[![Clojars](https://img.shields.io/clojars/v/de.timokramer/charm.clj.svg)](https://clojars.org/de.timokramer/charm.clj) -via github ```clojure -{:deps {io.github.timokramer/charm.clj {:git/tag "v0.1.64" :git/sha "e5120a9"}}} +{:deps {de.timokramer/charm.clj {:mvn/version "VERSION"}}} ``` -or via clojars maven repository + +[![GitHub tag](https://img.shields.io/github/v/tag/TimoKramer/charm.clj)](https://github.com/TimoKramer/charm.clj/tags) + ```clojure -{:deps {de.timokramer/charm.clj {:mvn/version "0.1.64"}}} +{:deps {io.github.timokramer/charm.clj {:git/tag "TAG" :git/sha "SHA"}}} ``` diff --git a/build.clj b/build.clj index 4076bd3..c2f8a97 100644 --- a/build.clj +++ b/build.clj @@ -5,7 +5,7 @@ [deps-deploy.deps-deploy :as dd])) (def lib 'de.timokramer/charm.clj) -(def version "0.1.") +(def version "0.2.") (def class-dir "target/classes") (defn- version-str [] From 0d587fcbc5935da0d5540d1aa52f0af79481d25f Mon Sep 17 00:00:00 2001 From: Timo Kramer Date: Wed, 8 Apr 2026 13:17:45 +0200 Subject: [PATCH 2/6] fix: mouse message API and improve public API surface - Fix mouse message conversion in program.clj: args were passed in wrong order and integer button codes were not converted to keywords - Add mouse predicates to charm.message (click?, left-click?, wheel-up?, etc.) so users don't need charm.input.mouse - Re-export width utilities (string-width, truncate, pad-right, pad-left, strip-ansi) from charm.style.core - Add ^:no-doc to internal namespaces (terminal, render.*, input.*, ansi.*, style.color, style.layout) - Add cljdoc.edn with structured article tree - Add sketch example demonstrating mouse interaction - Update README features list with viewport and table components --- README.md | 2 +- doc/cljdoc.edn | 27 ++++++ docs/examples/src/examples/sketch.clj | 128 ++++++++++++++++++++++++++ src/charm/ansi/parser.clj | 2 +- src/charm/ansi/width.clj | 2 +- src/charm/input/handler.clj | 2 +- src/charm/input/keymap.clj | 2 +- src/charm/input/keys.clj | 2 +- src/charm/input/mouse.clj | 2 +- src/charm/message.clj | 49 ++++++++++ src/charm/program.clj | 20 +++- src/charm/render/core.clj | 2 +- src/charm/render/screen.clj | 2 +- src/charm/style/color.clj | 2 +- src/charm/style/core.clj | 7 ++ src/charm/style/layout.clj | 2 +- src/charm/terminal.clj | 2 +- test/charm/message_test.clj | 40 +++++++- 18 files changed, 277 insertions(+), 18 deletions(-) create mode 100644 doc/cljdoc.edn create mode 100644 docs/examples/src/examples/sketch.clj diff --git a/README.md b/README.md index 14d1511..1ff13b0 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ encounter any issues. ## Features - **Elm Architecture** - Simple init/update/view pattern for predictable state management -- **UI Components** - Spinner, text-input, list, paginator, timer, progress, help +- **UI Components** - Spinner, text-input, list, paginator, timer, progress, help, viewport, table - **Styling** - Colors (ANSI, 256, true color), borders, padding, alignment - **Input handling** - Keyboard and mouse events with modifier support - **Efficient rendering** - Line diffing for minimal terminal updates diff --git a/doc/cljdoc.edn b/doc/cljdoc.edn new file mode 100644 index 0000000..457cdaf --- /dev/null +++ b/doc/cljdoc.edn @@ -0,0 +1,27 @@ +{:cljdoc.doc/tree + [["Getting Started" {:file "docs/guides/getting-started.md"}] + ["Components" {:file "docs/components/overview.md"} + ["Spinner" {:file "docs/components/spinner.md"}] + ["Text Input" {:file "docs/components/text-input.md"}] + ["List" {:file "docs/components/list.md"}] + ["Paginator" {:file "docs/components/paginator.md"}] + ["Timer" {:file "docs/components/timer.md"}] + ["Progress" {:file "docs/components/progress.md"}] + ["Help" {:file "docs/components/help.md"}]] + ["API Reference" {} + ["Program" {:file "docs/api/program.md"}] + ["Messages" {:file "docs/api/messages.md"}] + ["Styling" {:file "docs/api/styling.md"}] + ["Layout" {:file "docs/api/layout.md"}]] + ["Guides" {} + ["Component Composition" {:file "docs/guides/component-composition.md"}] + ["Styling Patterns" {:file "docs/guides/styling-patterns.md"}]] + ["Examples" {:file "docs/examples/README.md"}] + ["Architecture Decision Records" {} + ["ADR 001: BreakIterator ICU4J vs JDK" {:file "docs/adr/001-breakiterator-icu4j-vs-jdk.md"}] + ["ADR 002: JLine FFM vs JNI" {:file "docs/adr/002-jline-ffm-vs-jni.md"}] + ["ADR 003: Testing Strategy" {:file "docs/adr/003-testing-strategy.md"}] + ["ADR 004: JLine Input API Choices" {:file "docs/adr/004-jline-input-api-choices.md"}] + ["ADR 005: Layout Primitives" {:file "docs/adr/005-layout-primitives.md"}] + ["ADR 006: Remove charm.core Facade" {:file "docs/adr/006-remove-charm-core-facade.md"}] + ["ADR 006: Grapheme Cluster Width" {:file "docs/adr/006-grapheme-cluster-width.md"}]]]} diff --git a/docs/examples/src/examples/sketch.clj b/docs/examples/src/examples/sketch.clj new file mode 100644 index 0000000..58b1040 --- /dev/null +++ b/docs/examples/src/examples/sketch.clj @@ -0,0 +1,128 @@ +(ns examples.sketch + "A mouse-driven drawing pad. + Click/drag to draw, right-click to erase, scroll to change brush. + Demonstrates mouse interaction in charm.clj." + (:require + [charm.message :as msg] + [charm.program :as program] + [charm.style.core :as style] + [clojure.string :as str])) + +;; --------------------------------------------------------------------------- +;; Brushes +;; --------------------------------------------------------------------------- + +(def brushes ["█" "░" "▒" "▓" "●" "◆" "★" "♦" "╳" "○"]) + +;; --------------------------------------------------------------------------- +;; Styles +;; --------------------------------------------------------------------------- + +(def title-style + (style/style :fg style/magenta :bold true)) + +(def help-style + (style/style :fg style/white :faint true)) + +(def brush-style + (style/style :fg style/cyan :bold true)) + +;; --------------------------------------------------------------------------- +;; Init +;; --------------------------------------------------------------------------- + +(defn init [] + [{:canvas {} + :brush-idx 0 + :width 80 + :height 24 + :mouse-pos nil} + nil]) + +;; --------------------------------------------------------------------------- +;; Update +;; --------------------------------------------------------------------------- + +(defn- draw [canvas x y brush] + (assoc canvas [x y] brush)) + +(defn update-fn [state msg] + (cond + (or (msg/key-match? msg "q") + (msg/key-match? msg "ctrl+c")) + [state program/quit-cmd] + + (msg/key-match? msg "c") + [(assoc state :canvas {}) nil] + + (msg/window-size? msg) + [(assoc state + :width (:width msg) + :height (:height msg)) + nil] + + ;; Left click or drag: draw + (or (msg/left-click? msg) + (and (msg/motion? msg) (= :left (:button msg)))) + (let [brush (nth brushes (:brush-idx state))] + [(-> state + (update :canvas draw (:x msg) (:y msg) brush) + (assoc :mouse-pos [(:x msg) (:y msg)])) + nil]) + + ;; Right click or drag: erase + (or (msg/right-click? msg) + (and (msg/motion? msg) (= :right (:button msg)))) + [(-> state + (update :canvas dissoc [(:x msg) (:y msg)]) + (assoc :mouse-pos [(:x msg) (:y msg)])) + nil] + + ;; Track mouse position on any motion + (msg/motion? msg) + [(assoc state :mouse-pos [(:x msg) (:y msg)]) nil] + + ;; Scroll wheel: cycle brush + (msg/wheel-up? msg) + [(update state :brush-idx #(mod (dec %) (count brushes))) nil] + + (msg/wheel-down? msg) + [(update state :brush-idx #(mod (inc %) (count brushes))) nil] + + :else + [state nil])) + +;; --------------------------------------------------------------------------- +;; View +;; --------------------------------------------------------------------------- + +(defn view [state] + (let [{:keys [canvas brush-idx width height mouse-pos]} state + brush (nth brushes brush-idx) + ;; Reserve 2 lines for status bar + canvas-height (- height 2)] + (str + ;; Canvas area + (str/join + "\n" + (for [y (range 1 (inc canvas-height))] + (apply str + (for [x (range 1 (inc width))] + (get canvas [x y] " "))))) + "\n" + ;; Status bar + (style/render title-style "Sketch") + " " + (style/render brush-style (str "Brush: " brush)) + (when mouse-pos + (str " " (style/styled (str "(" (first mouse-pos) "," (second mouse-pos) ")") + :faint true))) + "\n" + (style/render help-style "click:draw right-click:erase scroll:brush c:clear q:quit")))) + +(defn -main [& _args] + (program/run {:init init + :update update-fn + :view view + :alt-screen true + :mouse :cell})) diff --git a/src/charm/ansi/parser.clj b/src/charm/ansi/parser.clj index 0c46fdf..4f043e4 100644 --- a/src/charm/ansi/parser.clj +++ b/src/charm/ansi/parser.clj @@ -1,4 +1,4 @@ -(ns charm.ansi.parser +(ns ^:no-doc charm.ansi.parser "ANSI escape sequence parsing. Parses ANSI escape sequences into structured data for processing." diff --git a/src/charm/ansi/width.clj b/src/charm/ansi/width.clj index 3260ecc..e558079 100644 --- a/src/charm/ansi/width.clj +++ b/src/charm/ansi/width.clj @@ -1,4 +1,4 @@ -(ns charm.ansi.width +(ns ^:no-doc charm.ansi.width "Text width calculation for terminal display. Handles: diff --git a/src/charm/input/handler.clj b/src/charm/input/handler.clj index 290b91e..b3d2014 100644 --- a/src/charm/input/handler.clj +++ b/src/charm/input/handler.clj @@ -1,4 +1,4 @@ -(ns charm.input.handler +(ns ^:no-doc charm.input.handler "Terminal input handling. Reads raw terminal input and converts it to structured diff --git a/src/charm/input/keymap.clj b/src/charm/input/keymap.clj index f7a6c58..16edcb1 100644 --- a/src/charm/input/keymap.clj +++ b/src/charm/input/keymap.clj @@ -1,4 +1,4 @@ -(ns charm.input.keymap +(ns ^:no-doc charm.input.keymap "JLine KeyMap-based escape sequence handling. Uses JLine's KeyMap for efficient O(1) escape sequence lookup diff --git a/src/charm/input/keys.clj b/src/charm/input/keys.clj index 097320c..3ccdc4d 100644 --- a/src/charm/input/keys.clj +++ b/src/charm/input/keys.clj @@ -1,4 +1,4 @@ -(ns charm.input.keys +(ns ^:no-doc charm.input.keys "Key sequence definitions and parsing. Maps terminal escape sequences to key types and provides diff --git a/src/charm/input/mouse.clj b/src/charm/input/mouse.clj index 26cb573..b64f8d1 100644 --- a/src/charm/input/mouse.clj +++ b/src/charm/input/mouse.clj @@ -1,4 +1,4 @@ -(ns charm.input.mouse +(ns ^:no-doc charm.input.mouse "Mouse event parsing for terminal input. Supports: diff --git a/src/charm/message.clj b/src/charm/message.clj index 293216f..88bb093 100644 --- a/src/charm/message.clj +++ b/src/charm/message.clj @@ -165,3 +165,52 @@ "Check if shift modifier is set." [msg] (:shift msg false)) + +;; --------------------------------------------------------------------------- +;; Mouse Helpers +;; --------------------------------------------------------------------------- + +(defn click? + "Check if a mouse message is a click (press action)." + [msg] + (and (mouse? msg) (= :press (:action msg)))) + +(defn release? + "Check if a mouse message is a release." + [msg] + (and (mouse? msg) (= :release (:action msg)))) + +(defn motion? + "Check if a mouse message is motion (drag)." + [msg] + (and (mouse? msg) (= :motion (:action msg)))) + +(defn left-click? + "Check if a mouse message is a left click." + [msg] + (and (click? msg) (= :left (:button msg)))) + +(defn right-click? + "Check if a mouse message is a right click." + [msg] + (and (click? msg) (= :right (:button msg)))) + +(defn middle-click? + "Check if a mouse message is a middle click." + [msg] + (and (click? msg) (= :middle (:button msg)))) + +(defn wheel-up? + "Check if a mouse message is a wheel up event." + [msg] + (and (mouse? msg) (= :wheel-up (:action msg)))) + +(defn wheel-down? + "Check if a mouse message is a wheel down event." + [msg] + (and (mouse? msg) (= :wheel-down (:action msg)))) + +(defn wheel? + "Check if a mouse message is any wheel event." + [msg] + (or (wheel-up? msg) (wheel-down? msg))) diff --git a/src/charm/program.clj b/src/charm/program.clj index 30bc6b3..ef45909 100644 --- a/src/charm/program.clj +++ b/src/charm/program.clj @@ -112,11 +112,21 @@ ;; Convert input event to message (let [m (cond (= :mouse (:type event)) - (msg/mouse (:button event) (:x event) (:y event) - :action (:action event) - :ctrl (:ctrl event) - :alt (:alt event) - :shift (:shift event)) + (let [raw-button (:button event) + wheel (case (int raw-button) + 4 :wheel-up 5 :wheel-down + 6 :wheel-left 7 :wheel-right + nil)] + (msg/mouse (if wheel wheel (:action event)) + (if wheel + :none + (case (int raw-button) + 0 :left 1 :middle 2 :right + :none)) + (:x event) (:y event) + :ctrl (:ctrl event) + :alt (:alt event) + :shift (:shift event))) (= :focus (:type event)) (msg/focus) diff --git a/src/charm/render/core.clj b/src/charm/render/core.clj index e44b189..0a72fe9 100644 --- a/src/charm/render/core.clj +++ b/src/charm/render/core.clj @@ -1,4 +1,4 @@ -(ns charm.render.core +(ns ^:no-doc charm.render.core "Terminal renderer using JLine's Display for efficient diffing. Provides a high-level rendering API that efficiently updates diff --git a/src/charm/render/screen.clj b/src/charm/render/screen.clj index 81ff595..d7001d3 100644 --- a/src/charm/render/screen.clj +++ b/src/charm/render/screen.clj @@ -1,4 +1,4 @@ -(ns charm.render.screen +(ns ^:no-doc charm.render.screen "ANSI control sequences for terminal features without JLine capability equivalents. For cursor movement, screen clearing, and alt screen, use charm.terminal diff --git a/src/charm/style/color.clj b/src/charm/style/color.clj index a2d7ec1..6ec87e1 100644 --- a/src/charm/style/color.clj +++ b/src/charm/style/color.clj @@ -1,4 +1,4 @@ -(ns charm.style.color +(ns ^:no-doc charm.style.color "Terminal color handling. Supports: diff --git a/src/charm/style/core.clj b/src/charm/style/core.clj index 0b6c558..2f78db6 100644 --- a/src/charm/style/core.clj +++ b/src/charm/style/core.clj @@ -274,6 +274,13 @@ (def join-horizontal l/join-horizontal) (def join-vertical l/join-vertical) +;; Text width utilities +(def string-width w/string-width) +(def truncate w/truncate) +(def pad-right w/pad-right) +(def pad-left w/pad-left) +(def strip-ansi w/strip-ansi) + ;; --------------------------------------------------------------------------- ;; Frame Size Calculation ;; --------------------------------------------------------------------------- diff --git a/src/charm/style/layout.clj b/src/charm/style/layout.clj index 8c5ef75..15c3938 100644 --- a/src/charm/style/layout.clj +++ b/src/charm/style/layout.clj @@ -1,4 +1,4 @@ -(ns charm.style.layout +(ns ^:no-doc charm.style.layout "Layout utilities: padding, margin, alignment, and joining." (:require [charm.ansi.width :as w] [charm.style.color :as color] diff --git a/src/charm/terminal.clj b/src/charm/terminal.clj index ee2f269..42bea63 100644 --- a/src/charm/terminal.clj +++ b/src/charm/terminal.clj @@ -1,4 +1,4 @@ -(ns charm.terminal +(ns ^:no-doc charm.terminal "JLine terminal wrapper for charm.clj" (:import [org.jline.terminal Terminal TerminalBuilder Attributes] [org.jline.utils InfoCmp$Capability])) diff --git a/test/charm/message_test.clj b/test/charm/message_test.clj index 600bd15..67ce2c6 100644 --- a/test/charm/message_test.clj +++ b/test/charm/message_test.clj @@ -78,4 +78,42 @@ (testing "mouse?" (is (msg/mouse? (msg/mouse :press :left 0 0))) - (is (not (msg/mouse? (msg/quit)))))) + (is (not (msg/mouse? (msg/quit))))) + + (testing "click?" + (is (msg/click? (msg/mouse :press :left 10 20))) + (is (not (msg/click? (msg/mouse :release :none 10 20)))) + (is (not (msg/click? (msg/quit))))) + + (testing "release?" + (is (msg/release? (msg/mouse :release :none 10 20))) + (is (not (msg/release? (msg/mouse :press :left 10 20))))) + + (testing "motion?" + (is (msg/motion? (msg/mouse :motion :left 10 20))) + (is (not (msg/motion? (msg/mouse :press :left 10 20))))) + + (testing "left-click?" + (is (msg/left-click? (msg/mouse :press :left 10 20))) + (is (not (msg/left-click? (msg/mouse :press :right 10 20))))) + + (testing "right-click?" + (is (msg/right-click? (msg/mouse :press :right 10 20))) + (is (not (msg/right-click? (msg/mouse :press :left 10 20))))) + + (testing "middle-click?" + (is (msg/middle-click? (msg/mouse :press :middle 10 20))) + (is (not (msg/middle-click? (msg/mouse :press :left 10 20))))) + + (testing "wheel-up?" + (is (msg/wheel-up? (msg/mouse :wheel-up :none 10 20))) + (is (not (msg/wheel-up? (msg/mouse :wheel-down :none 10 20))))) + + (testing "wheel-down?" + (is (msg/wheel-down? (msg/mouse :wheel-down :none 10 20))) + (is (not (msg/wheel-down? (msg/mouse :press :left 10 20))))) + + (testing "wheel?" + (is (msg/wheel? (msg/mouse :wheel-up :none 10 20))) + (is (msg/wheel? (msg/mouse :wheel-down :none 10 20))) + (is (not (msg/wheel? (msg/mouse :press :left 10 20)))))) From 50140dadaa044667e2621f8fbf75dac1619fadd3 Mon Sep 17 00:00:00 2001 From: Timo Kramer Date: Wed, 8 Apr 2026 14:39:51 +0200 Subject: [PATCH 3/6] refactor: unified require --- src/charm/style/border.clj | 4 ++-- src/charm/style/layout.clj | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/charm/style/border.clj b/src/charm/style/border.clj index fe56e56..5d9df1d 100644 --- a/src/charm/style/border.clj +++ b/src/charm/style/border.clj @@ -4,7 +4,7 @@ Provides predefined border styles and functions for rendering borders around text content." (:require [charm.ansi.width :as w] - [charm.style.color :as color] + [charm.style.color :as c] [clojure.string :as str])) ;; --------------------------------------------------------------------------- @@ -106,7 +106,7 @@ (defn- style-text "Apply foreground and background color to text." [text fg bg] - (color/styled-str text :fg fg :bg bg)) + (c/styled-str text :fg fg :bg bg)) (defn apply-border "Apply a border around text content. diff --git a/src/charm/style/layout.clj b/src/charm/style/layout.clj index 15c3938..0e0288e 100644 --- a/src/charm/style/layout.clj +++ b/src/charm/style/layout.clj @@ -1,7 +1,7 @@ (ns ^:no-doc charm.style.layout "Layout utilities: padding, margin, alignment, and joining." (:require [charm.ansi.width :as w] - [charm.style.color :as color] + [charm.style.color :as c] [clojure.string :as str])) ;; --------------------------------------------------------------------------- @@ -59,7 +59,7 @@ [n bg] (let [spaces (apply str (repeat n " "))] (if bg - (color/styled-str spaces :bg bg) + (c/styled-str spaces :bg bg) spaces))) ;; --------------------------------------------------------------------------- From e1125f57313482c8f9f189173c2636a903f787e8 Mon Sep 17 00:00:00 2001 From: Timo Kramer Date: Wed, 8 Apr 2026 14:47:24 +0200 Subject: [PATCH 4/6] docs: rename docs folder to match cljdoc config --- AGENTS.md | 2 +- README.md | 22 +- .../adr/001-breakiterator-icu4j-vs-jdk.md | 0 {docs => doc}/adr/002-jline-ffm-vs-jni.md | 0 {docs => doc}/adr/003-testing-strategy.md | 0 .../adr/004-jline-input-api-choices.md | 0 {docs => doc}/adr/005-layout-primitives.md | 0 .../adr/006-remove-charm-core-facade.md | 0 .../adr/007-grapheme-cluster-width.md | 2 +- {docs => doc}/api/layout.md | 0 {docs => doc}/api/messages.md | 0 {docs => doc}/api/program.md | 0 {docs => doc}/api/styling.md | 0 doc/cljdoc.edn | 46 +- {docs => doc}/components/help.md | 0 {docs => doc}/components/list.md | 0 {docs => doc}/components/overview.md | 0 {docs => doc}/components/paginator.md | 0 {docs => doc}/components/progress.md | 0 {docs => doc}/components/spinner.md | 0 {docs => doc}/components/text-input.md | 0 {docs => doc}/components/timer.md | 0 {docs => doc}/examples/README.md | 0 {docs => doc}/examples/bb.edn | 0 {docs => doc}/examples/build.clj | 2 +- {docs => doc}/examples/deps.edn | 0 {docs => doc}/examples/images/countdown.gif | Bin {docs => doc}/examples/images/counter.gif | Bin {docs => doc}/examples/images/download.gif | Bin .../examples/images/file_browser.gif | Bin {docs => doc}/examples/images/form.gif | Bin {docs => doc}/examples/images/pomodoro.gif | Bin {docs => doc}/examples/images/spinner.gif | Bin {docs => doc}/examples/images/todos.gif | Bin .../examples/src/examples/cheatsheet.clj | 2 +- .../examples/src/examples/cheatsheet/data.clj | 0 .../examples/src/examples/countdown.clj | 0 .../examples/src/examples/counter.clj | 0 .../examples/src/examples/download.clj | 0 .../examples/src/examples/emoji_width.clj | 0 .../examples/src/examples/file_browser.clj | 0 {docs => doc}/examples/src/examples/form.clj | 0 .../examples/src/examples/pomodoro.clj | 0 .../examples/src/examples/sketch.clj | 0 .../examples/src/examples/spinner_demo.clj | 0 {docs => doc}/examples/src/examples/timer.clj | 0 {docs => doc}/examples/src/examples/todos.clj | 0 {docs => doc}/examples/test/download.ascii | 0 {docs => doc}/examples/test/pomodoro.ascii | 0 {docs => doc}/examples/vhs/countdown.tape | 0 {docs => doc}/examples/vhs/counter.tape | 0 {docs => doc}/examples/vhs/download.tape | 0 {docs => doc}/examples/vhs/file_browser.tape | 0 {docs => doc}/examples/vhs/form.tape | 0 {docs => doc}/examples/vhs/pomodoro.tape | 0 {docs => doc}/examples/vhs/spinner.tape | 0 {docs => doc}/examples/vhs/todos.tape | 0 {docs => doc}/guides/component-composition.md | 0 {docs => doc}/guides/getting-started.md | 0 {docs => doc}/guides/styling-patterns.md | 0 .../timer/native-image.properties | 7 - .../timer/reachability-metadata.json | 2028 ----------------- .../native-image/timer/reflect-config.json | 64 - .../native-image/timer/resource-config.json | 11 - 64 files changed, 38 insertions(+), 2148 deletions(-) rename {docs => doc}/adr/001-breakiterator-icu4j-vs-jdk.md (100%) rename {docs => doc}/adr/002-jline-ffm-vs-jni.md (100%) rename {docs => doc}/adr/003-testing-strategy.md (100%) rename {docs => doc}/adr/004-jline-input-api-choices.md (100%) rename {docs => doc}/adr/005-layout-primitives.md (100%) rename {docs => doc}/adr/006-remove-charm-core-facade.md (100%) rename docs/adr/006-grapheme-cluster-width.md => doc/adr/007-grapheme-cluster-width.md (98%) rename {docs => doc}/api/layout.md (100%) rename {docs => doc}/api/messages.md (100%) rename {docs => doc}/api/program.md (100%) rename {docs => doc}/api/styling.md (100%) rename {docs => doc}/components/help.md (100%) rename {docs => doc}/components/list.md (100%) rename {docs => doc}/components/overview.md (100%) rename {docs => doc}/components/paginator.md (100%) rename {docs => doc}/components/progress.md (100%) rename {docs => doc}/components/spinner.md (100%) rename {docs => doc}/components/text-input.md (100%) rename {docs => doc}/components/timer.md (100%) rename {docs => doc}/examples/README.md (100%) rename {docs => doc}/examples/bb.edn (100%) rename {docs => doc}/examples/build.clj (97%) rename {docs => doc}/examples/deps.edn (100%) rename {docs => doc}/examples/images/countdown.gif (100%) rename {docs => doc}/examples/images/counter.gif (100%) rename {docs => doc}/examples/images/download.gif (100%) rename {docs => doc}/examples/images/file_browser.gif (100%) rename {docs => doc}/examples/images/form.gif (100%) rename {docs => doc}/examples/images/pomodoro.gif (100%) rename {docs => doc}/examples/images/spinner.gif (100%) rename {docs => doc}/examples/images/todos.gif (100%) rename {docs => doc}/examples/src/examples/cheatsheet.clj (99%) rename {docs => doc}/examples/src/examples/cheatsheet/data.clj (100%) rename {docs => doc}/examples/src/examples/countdown.clj (100%) rename {docs => doc}/examples/src/examples/counter.clj (100%) rename {docs => doc}/examples/src/examples/download.clj (100%) rename {docs => doc}/examples/src/examples/emoji_width.clj (100%) rename {docs => doc}/examples/src/examples/file_browser.clj (100%) rename {docs => doc}/examples/src/examples/form.clj (100%) rename {docs => doc}/examples/src/examples/pomodoro.clj (100%) rename {docs => doc}/examples/src/examples/sketch.clj (100%) rename {docs => doc}/examples/src/examples/spinner_demo.clj (100%) rename {docs => doc}/examples/src/examples/timer.clj (100%) rename {docs => doc}/examples/src/examples/todos.clj (100%) rename {docs => doc}/examples/test/download.ascii (100%) rename {docs => doc}/examples/test/pomodoro.ascii (100%) rename {docs => doc}/examples/vhs/countdown.tape (100%) rename {docs => doc}/examples/vhs/counter.tape (100%) rename {docs => doc}/examples/vhs/download.tape (100%) rename {docs => doc}/examples/vhs/file_browser.tape (100%) rename {docs => doc}/examples/vhs/form.tape (100%) rename {docs => doc}/examples/vhs/pomodoro.tape (100%) rename {docs => doc}/examples/vhs/spinner.tape (100%) rename {docs => doc}/examples/vhs/todos.tape (100%) rename {docs => doc}/guides/component-composition.md (100%) rename {docs => doc}/guides/getting-started.md (100%) rename {docs => doc}/guides/styling-patterns.md (100%) delete mode 100644 docs/examples/resources/META-INF/native-image/timer/native-image.properties delete mode 100644 docs/examples/resources/META-INF/native-image/timer/reachability-metadata.json delete mode 100644 docs/examples/resources/META-INF/native-image/timer/reflect-config.json delete mode 100644 docs/examples/resources/META-INF/native-image/timer/resource-config.json diff --git a/AGENTS.md b/AGENTS.md index 2a6359c..4e8b1a1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -66,7 +66,7 @@ clojure -M -m examples.file-browser ## Running Tests via REPL -See [ADR 003: Testing Strategy](docs/adr/003-testing-strategy.md) for the full decision record. +See [ADR 003: Testing Strategy](doc/adr/003-testing-strategy.md) for the full decision record. ## Three-Tier Testing Strategy diff --git a/README.md b/README.md index 1ff13b0..c50c2ac 100644 --- a/README.md +++ b/README.md @@ -25,18 +25,18 @@ encounter any issues. ## Documentation -- **[Getting Started](docs/guides/getting-started.md)** - Build your first app -- **[Components](docs/components/overview.md)** - UI component reference - - [spinner](docs/components/spinner.md), [text-input](docs/components/text-input.md), [list](docs/components/list.md), [paginator](docs/components/paginator.md), [timer](docs/components/timer.md), [progress](docs/components/progress.md), [help](docs/components/help.md) +- **[Getting Started](doc/guides/getting-started.md)** - Build your first app +- **[Components](doc/components/overview.md)** - UI component reference + - [spinner](doc/components/spinner.md), [text-input](doc/components/text-input.md), [list](doc/components/list.md), [paginator](doc/components/paginator.md), [timer](doc/components/timer.md), [progress](doc/components/progress.md), [help](doc/components/help.md) - **API Reference** - - [Program](docs/api/program.md) - run, cmd, batch, quit-cmd - - [Messages](docs/api/messages.md) - key-press, mouse, window-size - - [Styling](docs/api/styling.md) - style, render, colors, borders - - [Layout](docs/api/layout.md) - join-horizontal, join-vertical + - [Program](doc/api/program.md) - run, cmd, batch, quit-cmd + - [Messages](doc/api/messages.md) - key-press, mouse, window-size + - [Styling](doc/api/styling.md) - style, render, colors, borders + - [Layout](doc/api/layout.md) - join-horizontal, join-vertical - **Guides** - - [Component Composition](docs/guides/component-composition.md) - - [Styling Patterns](docs/guides/styling-patterns.md) -- **[Examples](docs/examples/README.md)** - Runnable demo applications + - [Component Composition](doc/guides/component-composition.md) + - [Styling Patterns](doc/guides/styling-patterns.md) +- **[Examples](doc/examples/README.md)** - Runnable demo applications ## Installation @@ -179,7 +179,7 @@ program/quit-cmd ## Examples -Please take a look at the [examples](docs/examples/README.md) in the docs folder and don't hesitate to contribute your examples please. +Please take a look at the [examples](doc/examples/README.md) in the doc folder and don't hesitate to contribute your examples please. ## Project Structure diff --git a/docs/adr/001-breakiterator-icu4j-vs-jdk.md b/doc/adr/001-breakiterator-icu4j-vs-jdk.md similarity index 100% rename from docs/adr/001-breakiterator-icu4j-vs-jdk.md rename to doc/adr/001-breakiterator-icu4j-vs-jdk.md diff --git a/docs/adr/002-jline-ffm-vs-jni.md b/doc/adr/002-jline-ffm-vs-jni.md similarity index 100% rename from docs/adr/002-jline-ffm-vs-jni.md rename to doc/adr/002-jline-ffm-vs-jni.md diff --git a/docs/adr/003-testing-strategy.md b/doc/adr/003-testing-strategy.md similarity index 100% rename from docs/adr/003-testing-strategy.md rename to doc/adr/003-testing-strategy.md diff --git a/docs/adr/004-jline-input-api-choices.md b/doc/adr/004-jline-input-api-choices.md similarity index 100% rename from docs/adr/004-jline-input-api-choices.md rename to doc/adr/004-jline-input-api-choices.md diff --git a/docs/adr/005-layout-primitives.md b/doc/adr/005-layout-primitives.md similarity index 100% rename from docs/adr/005-layout-primitives.md rename to doc/adr/005-layout-primitives.md diff --git a/docs/adr/006-remove-charm-core-facade.md b/doc/adr/006-remove-charm-core-facade.md similarity index 100% rename from docs/adr/006-remove-charm-core-facade.md rename to doc/adr/006-remove-charm-core-facade.md diff --git a/docs/adr/006-grapheme-cluster-width.md b/doc/adr/007-grapheme-cluster-width.md similarity index 98% rename from docs/adr/006-grapheme-cluster-width.md rename to doc/adr/007-grapheme-cluster-width.md index a9c7887..9a38cb3 100644 --- a/docs/adr/006-grapheme-cluster-width.md +++ b/doc/adr/007-grapheme-cluster-width.md @@ -1,4 +1,4 @@ -# ADR 006: Grapheme Cluster Width via JLine 4 Mode 2027 +# ADR 007: Grapheme Cluster Width via JLine 4 Mode 2027 ## Status diff --git a/docs/api/layout.md b/doc/api/layout.md similarity index 100% rename from docs/api/layout.md rename to doc/api/layout.md diff --git a/docs/api/messages.md b/doc/api/messages.md similarity index 100% rename from docs/api/messages.md rename to doc/api/messages.md diff --git a/docs/api/program.md b/doc/api/program.md similarity index 100% rename from docs/api/program.md rename to doc/api/program.md diff --git a/docs/api/styling.md b/doc/api/styling.md similarity index 100% rename from docs/api/styling.md rename to doc/api/styling.md diff --git a/doc/cljdoc.edn b/doc/cljdoc.edn index 457cdaf..76fb5e7 100644 --- a/doc/cljdoc.edn +++ b/doc/cljdoc.edn @@ -1,27 +1,27 @@ {:cljdoc.doc/tree - [["Getting Started" {:file "docs/guides/getting-started.md"}] - ["Components" {:file "docs/components/overview.md"} - ["Spinner" {:file "docs/components/spinner.md"}] - ["Text Input" {:file "docs/components/text-input.md"}] - ["List" {:file "docs/components/list.md"}] - ["Paginator" {:file "docs/components/paginator.md"}] - ["Timer" {:file "docs/components/timer.md"}] - ["Progress" {:file "docs/components/progress.md"}] - ["Help" {:file "docs/components/help.md"}]] + [["Getting Started" {:file "doc/guides/getting-started.md"}] + ["Components" {:file "doc/components/overview.md"} + ["Spinner" {:file "doc/components/spinner.md"}] + ["Text Input" {:file "doc/components/text-input.md"}] + ["List" {:file "doc/components/list.md"}] + ["Paginator" {:file "doc/components/paginator.md"}] + ["Timer" {:file "doc/components/timer.md"}] + ["Progress" {:file "doc/components/progress.md"}] + ["Help" {:file "doc/components/help.md"}]] ["API Reference" {} - ["Program" {:file "docs/api/program.md"}] - ["Messages" {:file "docs/api/messages.md"}] - ["Styling" {:file "docs/api/styling.md"}] - ["Layout" {:file "docs/api/layout.md"}]] + ["Program" {:file "doc/api/program.md"}] + ["Messages" {:file "doc/api/messages.md"}] + ["Styling" {:file "doc/api/styling.md"}] + ["Layout" {:file "doc/api/layout.md"}]] ["Guides" {} - ["Component Composition" {:file "docs/guides/component-composition.md"}] - ["Styling Patterns" {:file "docs/guides/styling-patterns.md"}]] - ["Examples" {:file "docs/examples/README.md"}] + ["Component Composition" {:file "doc/guides/component-composition.md"}] + ["Styling Patterns" {:file "doc/guides/styling-patterns.md"}]] + ["Examples" {:file "doc/examples/README.md"}] ["Architecture Decision Records" {} - ["ADR 001: BreakIterator ICU4J vs JDK" {:file "docs/adr/001-breakiterator-icu4j-vs-jdk.md"}] - ["ADR 002: JLine FFM vs JNI" {:file "docs/adr/002-jline-ffm-vs-jni.md"}] - ["ADR 003: Testing Strategy" {:file "docs/adr/003-testing-strategy.md"}] - ["ADR 004: JLine Input API Choices" {:file "docs/adr/004-jline-input-api-choices.md"}] - ["ADR 005: Layout Primitives" {:file "docs/adr/005-layout-primitives.md"}] - ["ADR 006: Remove charm.core Facade" {:file "docs/adr/006-remove-charm-core-facade.md"}] - ["ADR 006: Grapheme Cluster Width" {:file "docs/adr/006-grapheme-cluster-width.md"}]]]} + ["ADR 001: BreakIterator ICU4J vs JDK" {:file "doc/adr/001-breakiterator-icu4j-vs-jdk.md"}] + ["ADR 002: JLine FFM vs JNI" {:file "doc/adr/002-jline-ffm-vs-jni.md"}] + ["ADR 003: Testing Strategy" {:file "doc/adr/003-testing-strategy.md"}] + ["ADR 004: JLine Input API Choices" {:file "doc/adr/004-jline-input-api-choices.md"}] + ["ADR 005: Layout Primitives" {:file "doc/adr/005-layout-primitives.md"}] + ["ADR 006: Remove charm.core Facade" {:file "doc/adr/006-remove-charm-core-facade.md"}] + ["ADR 007: Grapheme Cluster Width" {:file "doc/adr/007-grapheme-cluster-width.md"}]]]} diff --git a/docs/components/help.md b/doc/components/help.md similarity index 100% rename from docs/components/help.md rename to doc/components/help.md diff --git a/docs/components/list.md b/doc/components/list.md similarity index 100% rename from docs/components/list.md rename to doc/components/list.md diff --git a/docs/components/overview.md b/doc/components/overview.md similarity index 100% rename from docs/components/overview.md rename to doc/components/overview.md diff --git a/docs/components/paginator.md b/doc/components/paginator.md similarity index 100% rename from docs/components/paginator.md rename to doc/components/paginator.md diff --git a/docs/components/progress.md b/doc/components/progress.md similarity index 100% rename from docs/components/progress.md rename to doc/components/progress.md diff --git a/docs/components/spinner.md b/doc/components/spinner.md similarity index 100% rename from docs/components/spinner.md rename to doc/components/spinner.md diff --git a/docs/components/text-input.md b/doc/components/text-input.md similarity index 100% rename from docs/components/text-input.md rename to doc/components/text-input.md diff --git a/docs/components/timer.md b/doc/components/timer.md similarity index 100% rename from docs/components/timer.md rename to doc/components/timer.md diff --git a/docs/examples/README.md b/doc/examples/README.md similarity index 100% rename from docs/examples/README.md rename to doc/examples/README.md diff --git a/docs/examples/bb.edn b/doc/examples/bb.edn similarity index 100% rename from docs/examples/bb.edn rename to doc/examples/bb.edn diff --git a/docs/examples/build.clj b/doc/examples/build.clj similarity index 97% rename from docs/examples/build.clj rename to doc/examples/build.clj index 8a266f3..4790e38 100644 --- a/docs/examples/build.clj +++ b/doc/examples/build.clj @@ -1,7 +1,7 @@ (ns build "Build script for timer CLI app. - Usage (from docs/examples directory): + Usage (from doc/examples directory): clj -T:build clean clj -T:build uber clj -T:build all ; clean + uber" diff --git a/docs/examples/deps.edn b/doc/examples/deps.edn similarity index 100% rename from docs/examples/deps.edn rename to doc/examples/deps.edn diff --git a/docs/examples/images/countdown.gif b/doc/examples/images/countdown.gif similarity index 100% rename from docs/examples/images/countdown.gif rename to doc/examples/images/countdown.gif diff --git a/docs/examples/images/counter.gif b/doc/examples/images/counter.gif similarity index 100% rename from docs/examples/images/counter.gif rename to doc/examples/images/counter.gif diff --git a/docs/examples/images/download.gif b/doc/examples/images/download.gif similarity index 100% rename from docs/examples/images/download.gif rename to doc/examples/images/download.gif diff --git a/docs/examples/images/file_browser.gif b/doc/examples/images/file_browser.gif similarity index 100% rename from docs/examples/images/file_browser.gif rename to doc/examples/images/file_browser.gif diff --git a/docs/examples/images/form.gif b/doc/examples/images/form.gif similarity index 100% rename from docs/examples/images/form.gif rename to doc/examples/images/form.gif diff --git a/docs/examples/images/pomodoro.gif b/doc/examples/images/pomodoro.gif similarity index 100% rename from docs/examples/images/pomodoro.gif rename to doc/examples/images/pomodoro.gif diff --git a/docs/examples/images/spinner.gif b/doc/examples/images/spinner.gif similarity index 100% rename from docs/examples/images/spinner.gif rename to doc/examples/images/spinner.gif diff --git a/docs/examples/images/todos.gif b/doc/examples/images/todos.gif similarity index 100% rename from docs/examples/images/todos.gif rename to doc/examples/images/todos.gif diff --git a/docs/examples/src/examples/cheatsheet.clj b/doc/examples/src/examples/cheatsheet.clj similarity index 99% rename from docs/examples/src/examples/cheatsheet.clj rename to doc/examples/src/examples/cheatsheet.clj index 324eed4..01f44c2 100644 --- a/docs/examples/src/examples/cheatsheet.clj +++ b/doc/examples/src/examples/cheatsheet.clj @@ -4,7 +4,7 @@ All sections are shown at once. Typing filters inline, showing only matching functions. Enter opens an overlay with documentation. - Run: cd docs/examples && clj -M -m examples.cheatsheet" + Run: cd doc/examples && clj -M -m examples.cheatsheet" (:require [charm.ansi.width :as ansi-width] [charm.components.help :as help] diff --git a/docs/examples/src/examples/cheatsheet/data.clj b/doc/examples/src/examples/cheatsheet/data.clj similarity index 100% rename from docs/examples/src/examples/cheatsheet/data.clj rename to doc/examples/src/examples/cheatsheet/data.clj diff --git a/docs/examples/src/examples/countdown.clj b/doc/examples/src/examples/countdown.clj similarity index 100% rename from docs/examples/src/examples/countdown.clj rename to doc/examples/src/examples/countdown.clj diff --git a/docs/examples/src/examples/counter.clj b/doc/examples/src/examples/counter.clj similarity index 100% rename from docs/examples/src/examples/counter.clj rename to doc/examples/src/examples/counter.clj diff --git a/docs/examples/src/examples/download.clj b/doc/examples/src/examples/download.clj similarity index 100% rename from docs/examples/src/examples/download.clj rename to doc/examples/src/examples/download.clj diff --git a/docs/examples/src/examples/emoji_width.clj b/doc/examples/src/examples/emoji_width.clj similarity index 100% rename from docs/examples/src/examples/emoji_width.clj rename to doc/examples/src/examples/emoji_width.clj diff --git a/docs/examples/src/examples/file_browser.clj b/doc/examples/src/examples/file_browser.clj similarity index 100% rename from docs/examples/src/examples/file_browser.clj rename to doc/examples/src/examples/file_browser.clj diff --git a/docs/examples/src/examples/form.clj b/doc/examples/src/examples/form.clj similarity index 100% rename from docs/examples/src/examples/form.clj rename to doc/examples/src/examples/form.clj diff --git a/docs/examples/src/examples/pomodoro.clj b/doc/examples/src/examples/pomodoro.clj similarity index 100% rename from docs/examples/src/examples/pomodoro.clj rename to doc/examples/src/examples/pomodoro.clj diff --git a/docs/examples/src/examples/sketch.clj b/doc/examples/src/examples/sketch.clj similarity index 100% rename from docs/examples/src/examples/sketch.clj rename to doc/examples/src/examples/sketch.clj diff --git a/docs/examples/src/examples/spinner_demo.clj b/doc/examples/src/examples/spinner_demo.clj similarity index 100% rename from docs/examples/src/examples/spinner_demo.clj rename to doc/examples/src/examples/spinner_demo.clj diff --git a/docs/examples/src/examples/timer.clj b/doc/examples/src/examples/timer.clj similarity index 100% rename from docs/examples/src/examples/timer.clj rename to doc/examples/src/examples/timer.clj diff --git a/docs/examples/src/examples/todos.clj b/doc/examples/src/examples/todos.clj similarity index 100% rename from docs/examples/src/examples/todos.clj rename to doc/examples/src/examples/todos.clj diff --git a/docs/examples/test/download.ascii b/doc/examples/test/download.ascii similarity index 100% rename from docs/examples/test/download.ascii rename to doc/examples/test/download.ascii diff --git a/docs/examples/test/pomodoro.ascii b/doc/examples/test/pomodoro.ascii similarity index 100% rename from docs/examples/test/pomodoro.ascii rename to doc/examples/test/pomodoro.ascii diff --git a/docs/examples/vhs/countdown.tape b/doc/examples/vhs/countdown.tape similarity index 100% rename from docs/examples/vhs/countdown.tape rename to doc/examples/vhs/countdown.tape diff --git a/docs/examples/vhs/counter.tape b/doc/examples/vhs/counter.tape similarity index 100% rename from docs/examples/vhs/counter.tape rename to doc/examples/vhs/counter.tape diff --git a/docs/examples/vhs/download.tape b/doc/examples/vhs/download.tape similarity index 100% rename from docs/examples/vhs/download.tape rename to doc/examples/vhs/download.tape diff --git a/docs/examples/vhs/file_browser.tape b/doc/examples/vhs/file_browser.tape similarity index 100% rename from docs/examples/vhs/file_browser.tape rename to doc/examples/vhs/file_browser.tape diff --git a/docs/examples/vhs/form.tape b/doc/examples/vhs/form.tape similarity index 100% rename from docs/examples/vhs/form.tape rename to doc/examples/vhs/form.tape diff --git a/docs/examples/vhs/pomodoro.tape b/doc/examples/vhs/pomodoro.tape similarity index 100% rename from docs/examples/vhs/pomodoro.tape rename to doc/examples/vhs/pomodoro.tape diff --git a/docs/examples/vhs/spinner.tape b/doc/examples/vhs/spinner.tape similarity index 100% rename from docs/examples/vhs/spinner.tape rename to doc/examples/vhs/spinner.tape diff --git a/docs/examples/vhs/todos.tape b/doc/examples/vhs/todos.tape similarity index 100% rename from docs/examples/vhs/todos.tape rename to doc/examples/vhs/todos.tape diff --git a/docs/guides/component-composition.md b/doc/guides/component-composition.md similarity index 100% rename from docs/guides/component-composition.md rename to doc/guides/component-composition.md diff --git a/docs/guides/getting-started.md b/doc/guides/getting-started.md similarity index 100% rename from docs/guides/getting-started.md rename to doc/guides/getting-started.md diff --git a/docs/guides/styling-patterns.md b/doc/guides/styling-patterns.md similarity index 100% rename from docs/guides/styling-patterns.md rename to doc/guides/styling-patterns.md diff --git a/docs/examples/resources/META-INF/native-image/timer/native-image.properties b/docs/examples/resources/META-INF/native-image/timer/native-image.properties deleted file mode 100644 index 6c4d37b..0000000 --- a/docs/examples/resources/META-INF/native-image/timer/native-image.properties +++ /dev/null @@ -1,7 +0,0 @@ -Args = --no-fallback \ - --features=clj_easy.graal_build_time.InitClojureClasses \ - -H:+ReportExceptionStackTraces \ - -H:+ForeignAPISupport \ - -H:+UnlockExperimentalVMOptions \ - --enable-native-access=ALL-UNNAMED \ - --enable-url-protocols=http,https diff --git a/docs/examples/resources/META-INF/native-image/timer/reachability-metadata.json b/docs/examples/resources/META-INF/native-image/timer/reachability-metadata.json deleted file mode 100644 index 9aa0521..0000000 --- a/docs/examples/resources/META-INF/native-image/timer/reachability-metadata.json +++ /dev/null @@ -1,2028 +0,0 @@ -{ - "foreign": { - "downcalls": [ - { - "parameterTypes": ["int", "long", "void*"], - "returnType": "int", - "options": {"firstVariadicArg": 2} - }, - { - "parameterTypes": ["int"], - "returnType": "int" - }, - { - "parameterTypes": ["int", "int", "void*"], - "returnType": "int" - }, - { - "parameterTypes": ["int", "void*"], - "returnType": "int" - }, - { - "parameterTypes": ["int", "void*", "long"], - "returnType": "int" - }, - { - "parameterTypes": ["void*", "void*", "void*", "void*", "void*"], - "returnType": "int" - }, - { - "parameterTypes": ["long", "int", "long", "long", "long"], - "returnType": "int" - } - ] - }, - "reflection": [ - { - "type": "boolean[]" - }, - { - "type": "byte[]" - }, - { - "type": "char[]" - }, - { - "type": "charm.ansi.width__init" - }, - { - "type": "charm.components.help__init" - }, - { - "type": "charm.components.list.ListItem" - }, - { - "type": "charm.components.list__init" - }, - { - "type": "charm.components.paginator__init" - }, - { - "type": "charm.components.progress__init" - }, - { - "type": "charm.components.spinner__init" - }, - { - "type": "charm.components.text_input__init" - }, - { - "type": "charm.components.timer__init" - }, - { - "type": "charm.core__init" - }, - { - "type": "charm.input.handler__init" - }, - { - "type": "charm.input.keys__init" - }, - { - "type": "charm.input.mouse__init" - }, - { - "type": "charm.message__init" - }, - { - "type": "charm.program__init" - }, - { - "type": "charm.render.core__init" - }, - { - "type": "charm.render.screen__init" - }, - { - "type": "charm.style.border__init" - }, - { - "type": "charm.style.color__init" - }, - { - "type": "charm.style.core__init" - }, - { - "type": "charm.style.layout__init" - }, - { - "type": "charm.terminal__init" - }, - { - "type": "clojure.asm.ClassReader" - }, - { - "type": "clojure.asm.ClassVisitor" - }, - { - "type": "clojure.asm.ClassWriter" - }, - { - "type": "clojure.asm.Opcodes" - }, - { - "type": "clojure.asm.Type" - }, - { - "type": "clojure.asm.commons.GeneratorAdapter" - }, - { - "type": "clojure.asm.commons.Method" - }, - { - "type": "clojure.core.ArrayChunk" - }, - { - "type": "clojure.core.ArrayManager" - }, - { - "type": "clojure.core.Eduction" - }, - { - "type": "clojure.core.IVecImpl" - }, - { - "type": "clojure.core.Inst" - }, - { - "type": "clojure.core.Vec" - }, - { - "type": "clojure.core.VecNode" - }, - { - "type": "clojure.core.VecSeq" - }, - { - "type": "clojure.core.async.Mix" - }, - { - "type": "clojure.core.async.Mult" - }, - { - "type": "clojure.core.async.Mux" - }, - { - "type": "clojure.core.async.Pub" - }, - { - "type": "clojure.core.async.impl.buffers.DroppingBuffer" - }, - { - "type": "clojure.core.async.impl.buffers.FixedBuffer" - }, - { - "type": "clojure.core.async.impl.buffers.PromiseBuffer" - }, - { - "type": "clojure.core.async.impl.buffers.SlidingBuffer" - }, - { - "type": "clojure.core.async.impl.buffers__init" - }, - { - "type": "clojure.core.async.impl.channels.MMC" - }, - { - "type": "clojure.core.async.impl.channels.ManyToManyChannel" - }, - { - "type": "clojure.core.async.impl.channels__init" - }, - { - "type": "clojure.core.async.impl.concurrent__init" - }, - { - "type": "clojure.core.async.impl.dispatch__init" - }, - { - "type": "clojure.core.async.impl.exec.threadpool__init" - }, - { - "type": "clojure.core.async.impl.ioc_macros.Call" - }, - { - "type": "clojure.core.async.impl.ioc_macros.Case" - }, - { - "type": "clojure.core.async.impl.ioc_macros.CatchHandler" - }, - { - "type": "clojure.core.async.impl.ioc_macros.CondBr" - }, - { - "type": "clojure.core.async.impl.ioc_macros.Const" - }, - { - "type": "clojure.core.async.impl.ioc_macros.CustomTerminator" - }, - { - "type": "clojure.core.async.impl.ioc_macros.Dot" - }, - { - "type": "clojure.core.async.impl.ioc_macros.EndFinally" - }, - { - "type": "clojure.core.async.impl.ioc_macros.Fn" - }, - { - "type": "clojure.core.async.impl.ioc_macros.IEmittableInstruction" - }, - { - "type": "clojure.core.async.impl.ioc_macros.IInstruction" - }, - { - "type": "clojure.core.async.impl.ioc_macros.ITerminator" - }, - { - "type": "clojure.core.async.impl.ioc_macros.InstanceInterop" - }, - { - "type": "clojure.core.async.impl.ioc_macros.Jmp" - }, - { - "type": "clojure.core.async.impl.ioc_macros.PopTry" - }, - { - "type": "clojure.core.async.impl.ioc_macros.PushTry" - }, - { - "type": "clojure.core.async.impl.ioc_macros.RawCode" - }, - { - "type": "clojure.core.async.impl.ioc_macros.Recur" - }, - { - "type": "clojure.core.async.impl.ioc_macros.Return" - }, - { - "type": "clojure.core.async.impl.ioc_macros.StaticCall" - }, - { - "type": "clojure.core.async.impl.ioc_macros__init" - }, - { - "type": "clojure.core.async.impl.mutex__init" - }, - { - "type": "clojure.core.async.impl.protocols.Buffer" - }, - { - "type": "clojure.core.async.impl.protocols.Channel" - }, - { - "type": "clojure.core.async.impl.protocols.Executor" - }, - { - "type": "clojure.core.async.impl.protocols.Handler" - }, - { - "type": "clojure.core.async.impl.protocols.ReadPort" - }, - { - "type": "clojure.core.async.impl.protocols.UnblockingBuffer" - }, - { - "type": "clojure.core.async.impl.protocols.WritePort" - }, - { - "type": "clojure.core.async.impl.protocols__init" - }, - { - "type": "clojure.core.async.impl.timers.TimeoutQueueEntry" - }, - { - "type": "clojure.core.async.impl.timers__init" - }, - { - "type": "clojure.core.async__init" - }, - { - "type": "clojure.core.cache.BasicCache" - }, - { - "type": "clojure.core.cache.CacheProtocol" - }, - { - "type": "clojure.core.cache.FIFOCache" - }, - { - "type": "clojure.core.cache.FnCache" - }, - { - "type": "clojure.core.cache.LIRSCache" - }, - { - "type": "clojure.core.cache.LRUCache" - }, - { - "type": "clojure.core.cache.LUCache" - }, - { - "type": "clojure.core.cache.SoftCache" - }, - { - "type": "clojure.core.cache.TTLCacheQ" - }, - { - "type": "clojure.core.cache__init" - }, - { - "type": "clojure.core.memoize.PluggableMemoization" - }, - { - "type": "clojure.core.memoize.RetryingDelay" - }, - { - "type": "clojure.core.memoize__init" - }, - { - "type": "clojure.core.protocols.CollReduce" - }, - { - "type": "clojure.core.protocols.Datafiable" - }, - { - "type": "clojure.core.protocols.IKVReduce" - }, - { - "type": "clojure.core.protocols.InternalReduce" - }, - { - "type": "clojure.core.protocols.Navigable" - }, - { - "type": "clojure.core.protocols__init" - }, - { - "type": "clojure.core.server__init" - }, - { - "type": "clojure.core__init" - }, - { - "type": "clojure.core_deftype__init" - }, - { - "type": "clojure.core_print__init" - }, - { - "type": "clojure.core_proxy__init" - }, - { - "type": "clojure.data.priority_map.PersistentPriorityMap" - }, - { - "type": "clojure.data.priority_map__init" - }, - { - "type": "clojure.datafy__init" - }, - { - "type": "clojure.edn__init" - }, - { - "type": "clojure.genclass__init" - }, - { - "type": "clojure.gvec__init" - }, - { - "type": "clojure.instant__init" - }, - { - "type": "clojure.java.io.Coercions" - }, - { - "type": "clojure.java.io.IOFactory" - }, - { - "type": "clojure.java.io__init" - }, - { - "type": "clojure.lang.AFn" - }, - { - "type": "clojure.lang.AFunction" - }, - { - "type": "clojure.lang.APersistentMap$KeySeq" - }, - { - "type": "clojure.lang.APersistentMap$ValSeq" - }, - { - "type": "clojure.lang.ASeq" - }, - { - "type": "clojure.lang.BigInt" - }, - { - "type": "clojure.lang.ChunkBuffer" - }, - { - "type": "clojure.lang.Compiler" - }, - { - "type": "clojure.lang.Compiler$CompilerException" - }, - { - "type": "clojure.lang.Cons" - }, - { - "type": "clojure.lang.Counted" - }, - { - "type": "clojure.lang.DynamicClassLoader" - }, - { - "type": "clojure.lang.ExceptionInfo" - }, - { - "type": "clojure.lang.Fn" - }, - { - "type": "clojure.lang.IChunk" - }, - { - "type": "clojure.lang.IChunkedSeq" - }, - { - "type": "clojure.lang.IDeref" - }, - { - "type": "clojure.lang.IExceptionInfo" - }, - { - "type": "clojure.lang.IFn" - }, - { - "type": "clojure.lang.IHashEq" - }, - { - "type": "clojure.lang.IKVReduce" - }, - { - "type": "clojure.lang.IMeta" - }, - { - "type": "clojure.lang.IObj" - }, - { - "type": "clojure.lang.IPersistentCollection" - }, - { - "type": "clojure.lang.IPersistentList" - }, - { - "type": "clojure.lang.IPersistentMap" - }, - { - "type": "clojure.lang.IPersistentSet" - }, - { - "type": "clojure.lang.IPersistentVector" - }, - { - "type": "clojure.lang.IProxy" - }, - { - "type": "clojure.lang.IRecord" - }, - { - "type": "clojure.lang.IReduceInit" - }, - { - "type": "clojure.lang.IRef" - }, - { - "type": "clojure.lang.IReference" - }, - { - "type": "clojure.lang.ISeq" - }, - { - "type": "clojure.lang.IType" - }, - { - "type": "clojure.lang.Keyword" - }, - { - "type": "clojure.lang.LazilyPersistentVector" - }, - { - "type": "clojure.lang.LazySeq" - }, - { - "type": "clojure.lang.LineNumberingPushbackReader" - }, - { - "type": "clojure.lang.LispReader$ReaderException" - }, - { - "type": "clojure.lang.MapEntry" - }, - { - "type": "clojure.lang.Murmur3" - }, - { - "type": "clojure.lang.Namespace" - }, - { - "type": "clojure.lang.Numbers" - }, - { - "type": "clojure.lang.PersistentArrayMap$Seq" - }, - { - "type": "clojure.lang.PersistentHashMap" - }, - { - "type": "clojure.lang.PersistentHashMap$NodeSeq" - }, - { - "type": "clojure.lang.PersistentHashSet" - }, - { - "type": "clojure.lang.PersistentQueue" - }, - { - "type": "clojure.lang.PersistentTreeMap" - }, - { - "type": "clojure.lang.PersistentVector" - }, - { - "type": "clojure.lang.PersistentVector$ChunkedSeq" - }, - { - "type": "clojure.lang.RT" - }, - { - "type": "clojure.lang.Ratio" - }, - { - "type": "clojure.lang.ReaderConditional" - }, - { - "type": "clojure.lang.Reflector" - }, - { - "type": "clojure.lang.SeqIterator" - }, - { - "type": "clojure.lang.Sequential" - }, - { - "type": "clojure.lang.StringSeq" - }, - { - "type": "clojure.lang.Symbol" - }, - { - "type": "clojure.lang.TaggedLiteral" - }, - { - "type": "clojure.lang.Util" - }, - { - "type": "clojure.lang.Var" - }, - { - "type": "clojure.lang.Volatile" - }, - { - "type": "clojure.main__init" - }, - { - "type": "clojure.pprint.PrettyFlush" - }, - { - "type": "clojure.pprint.cl_format__init" - }, - { - "type": "clojure.pprint.column_writer__init" - }, - { - "type": "clojure.pprint.dispatch__init" - }, - { - "type": "clojure.pprint.pprint_base__init" - }, - { - "type": "clojure.pprint.pretty_writer__init" - }, - { - "type": "clojure.pprint.print_table__init" - }, - { - "type": "clojure.pprint.utilities__init" - }, - { - "type": "clojure.pprint__init" - }, - { - "type": "clojure.reflect.AsmReflector" - }, - { - "type": "clojure.reflect.ClassResolver" - }, - { - "type": "clojure.reflect.Constructor" - }, - { - "type": "clojure.reflect.Field" - }, - { - "type": "clojure.reflect.JavaReflector" - }, - { - "type": "clojure.reflect.Method" - }, - { - "type": "clojure.reflect.Reflector" - }, - { - "type": "clojure.reflect.TypeReference" - }, - { - "type": "clojure.reflect.java__init" - }, - { - "type": "clojure.reflect__init" - }, - { - "type": "clojure.set__init" - }, - { - "type": "clojure.spec.alpha.Spec" - }, - { - "type": "clojure.spec.alpha.Specize" - }, - { - "type": "clojure.spec.alpha__init" - }, - { - "type": "clojure.spec.gen.alpha__init" - }, - { - "type": "clojure.string__init" - }, - { - "type": "clojure.tools.analyzer.ast__init" - }, - { - "type": "clojure.tools.analyzer.env__init" - }, - { - "type": "clojure.tools.analyzer.jvm.ExceptionThrown" - }, - { - "type": "clojure.tools.analyzer.jvm.utils__init" - }, - { - "type": "clojure.tools.analyzer.jvm__init" - }, - { - "type": "clojure.tools.analyzer.passes.add_binding_atom__init" - }, - { - "type": "clojure.tools.analyzer.passes.cleanup__init" - }, - { - "type": "clojure.tools.analyzer.passes.constant_lifter__init" - }, - { - "type": "clojure.tools.analyzer.passes.elide_meta__init" - }, - { - "type": "clojure.tools.analyzer.passes.emit_form__init" - }, - { - "type": "clojure.tools.analyzer.passes.jvm.analyze_host_expr__init" - }, - { - "type": "clojure.tools.analyzer.passes.jvm.annotate_host_info__init" - }, - { - "type": "clojure.tools.analyzer.passes.jvm.annotate_loops__init" - }, - { - "type": "clojure.tools.analyzer.passes.jvm.annotate_tag__init" - }, - { - "type": "clojure.tools.analyzer.passes.jvm.box__init" - }, - { - "type": "clojure.tools.analyzer.passes.jvm.classify_invoke__init" - }, - { - "type": "clojure.tools.analyzer.passes.jvm.constant_lifter__init" - }, - { - "type": "clojure.tools.analyzer.passes.jvm.emit_form__init" - }, - { - "type": "clojure.tools.analyzer.passes.jvm.fix_case_test__init" - }, - { - "type": "clojure.tools.analyzer.passes.jvm.infer_tag__init" - }, - { - "type": "clojure.tools.analyzer.passes.jvm.validate__init" - }, - { - "type": "clojure.tools.analyzer.passes.jvm.validate_loop_locals__init" - }, - { - "type": "clojure.tools.analyzer.passes.jvm.validate_recur__init" - }, - { - "type": "clojure.tools.analyzer.passes.jvm.warn_on_reflection__init" - }, - { - "type": "clojure.tools.analyzer.passes.source_info__init" - }, - { - "type": "clojure.tools.analyzer.passes.trim__init" - }, - { - "type": "clojure.tools.analyzer.passes.uniquify__init" - }, - { - "type": "clojure.tools.analyzer.passes.warn_earmuff__init" - }, - { - "type": "clojure.tools.analyzer.passes__init" - }, - { - "type": "clojure.tools.analyzer.utils__init" - }, - { - "type": "clojure.tools.analyzer__init" - }, - { - "type": "clojure.tools.reader.default_data_readers__init" - }, - { - "type": "clojure.tools.reader.impl.commons__init" - }, - { - "type": "clojure.tools.reader.impl.errors__init" - }, - { - "type": "clojure.tools.reader.impl.inspect__init" - }, - { - "type": "clojure.tools.reader.impl.utils__init" - }, - { - "type": "clojure.tools.reader.reader_types.IPushbackReader" - }, - { - "type": "clojure.tools.reader.reader_types.IndexingPushbackReader" - }, - { - "type": "clojure.tools.reader.reader_types.IndexingReader" - }, - { - "type": "clojure.tools.reader.reader_types.InputStreamReader" - }, - { - "type": "clojure.tools.reader.reader_types.PushbackReader" - }, - { - "type": "clojure.tools.reader.reader_types.PushbackReaderCoercer" - }, - { - "type": "clojure.tools.reader.reader_types.Reader" - }, - { - "type": "clojure.tools.reader.reader_types.ReaderCoercer" - }, - { - "type": "clojure.tools.reader.reader_types.SourceLoggingPushbackReader" - }, - { - "type": "clojure.tools.reader.reader_types.StringReader" - }, - { - "type": "clojure.tools.reader.reader_types__init" - }, - { - "type": "clojure.tools.reader__init" - }, - { - "type": "clojure.uuid__init" - }, - { - "type": "clojure.walk__init" - }, - { - "type": "double[]" - }, - { - "type": "examples.timer__init" - }, - { - "type": "float[]" - }, - { - "type": "int[]" - }, - { - "type": "java.io.BufferedInputStream" - }, - { - "type": "java.io.BufferedOutputStream" - }, - { - "type": "java.io.BufferedReader" - }, - { - "type": "java.io.BufferedWriter" - }, - { - "type": "java.io.ByteArrayInputStream" - }, - { - "type": "java.io.ByteArrayOutputStream" - }, - { - "type": "java.io.CharArrayReader" - }, - { - "type": "java.io.Closeable" - }, - { - "type": "java.io.File" - }, - { - "type": "java.io.FileInputStream" - }, - { - "type": "java.io.FileOutputStream" - }, - { - "type": "java.io.FileWriter" - }, - { - "type": "java.io.InputStream" - }, - { - "type": "java.io.InputStreamReader" - }, - { - "type": "java.io.NotSerializableException" - }, - { - "type": "java.io.OutputStream" - }, - { - "type": "java.io.OutputStreamWriter" - }, - { - "type": "java.io.PrintWriter", - "methods": [ - { - "name": "flush", - "parameterTypes": [] - }, - { - "name": "print", - "parameterTypes": [ - "java.lang.String" - ] - } - ] - }, - { - "type": "java.io.PushbackReader" - }, - { - "type": "java.io.Reader" - }, - { - "type": "java.io.Serializable" - }, - { - "type": "java.io.StringReader" - }, - { - "type": "java.io.Writer" - }, - { - "type": "java.lang.Boolean" - }, - { - "type": "java.lang.Byte" - }, - { - "type": "java.lang.Character" - }, - { - "type": "java.lang.Character$UnicodeBlock" - }, - { - "type": "java.lang.Class" - }, - { - "type": "java.lang.ClassLoader" - }, - { - "type": "java.lang.Double" - }, - { - "type": "java.lang.Enum", - "methods": [ - { - "name": "name", - "parameterTypes": [] - } - ] - }, - { - "type": "java.lang.Float" - }, - { - "type": "java.lang.Integer" - }, - { - "type": "java.lang.Iterable" - }, - { - "type": "java.lang.Long" - }, - { - "type": "java.lang.Number" - }, - { - "type": "java.lang.Object" - }, - { - "type": "java.lang.Object[]" - }, - { - "type": "java.lang.Runnable" - }, - { - "type": "java.lang.Short" - }, - { - "type": "java.lang.StackTraceElement" - }, - { - "type": "java.lang.String" - }, - { - "type": "java.lang.Thread", - "methods": [ - { - "name": "interrupt", - "parameterTypes": [] - }, - { - "name": "sleep", - "parameterTypes": [ - "long" - ] - } - ] - }, - { - "type": "java.lang.ThreadLocal" - }, - { - "type": "java.lang.Throwable" - }, - { - "type": "java.lang.UnsupportedOperationException" - }, - { - "type": "java.lang.Void" - }, - { - "type": "java.lang.annotation.Annotation" - }, - { - "type": "java.lang.annotation.Retention" - }, - { - "type": "java.lang.ref.ReferenceQueue" - }, - { - "type": "java.lang.ref.SoftReference" - }, - { - "type": "java.lang.reflect.Array" - }, - { - "type": "java.lang.reflect.Constructor" - }, - { - "type": "java.lang.reflect.Field" - }, - { - "type": "java.lang.reflect.Method", - "methods": [ - { - "name": "canAccess", - "parameterTypes": [ - "java.lang.Object" - ] - } - ] - }, - { - "type": "java.lang.reflect.Modifier" - }, - { - "type": "java.math.BigDecimal" - }, - { - "type": "java.math.BigInteger" - }, - { - "type": "java.net.InetAddress" - }, - { - "type": "java.net.MalformedURLException" - }, - { - "type": "java.net.ServerSocket" - }, - { - "type": "java.net.Socket" - }, - { - "type": "java.net.SocketException" - }, - { - "type": "java.net.URI" - }, - { - "type": "java.net.URL" - }, - { - "type": "java.net.URLDecoder" - }, - { - "type": "java.net.URLEncoder" - }, - { - "type": "java.nio.file.Files" - }, - { - "type": "java.nio.file.attribute.FileAttribute" - }, - { - "type": "java.sql.Timestamp" - }, - { - "type": "java.time.Instant" - }, - { - "type": "java.util.ArrayList" - }, - { - "type": "java.util.Arrays" - }, - { - "type": "java.util.Calendar" - }, - { - "type": "java.util.Collection" - }, - { - "type": "java.util.Date" - }, - { - "type": "java.util.GregorianCalendar" - }, - { - "type": "java.util.LinkedList" - }, - { - "type": "java.util.List" - }, - { - "type": "java.util.Locale", - "methods": [ - { - "name": "getDefault", - "parameterTypes": [ - "java.util.Locale$Category" - ] - } - ] - }, - { - "type": "java.util.Locale$Category" - }, - { - "type": "java.util.Map" - }, - { - "type": "java.util.Queue" - }, - { - "type": "java.util.RandomAccess" - }, - { - "type": "java.util.Set" - }, - { - "type": "java.util.TimeZone" - }, - { - "type": "java.util.UUID" - }, - { - "type": "java.util.concurrent.ArrayBlockingQueue" - }, - { - "type": "java.util.concurrent.BlockingQueue" - }, - { - "type": "java.util.concurrent.Callable" - }, - { - "type": "java.util.concurrent.ConcurrentHashMap" - }, - { - "type": "java.util.concurrent.ConcurrentSkipListMap" - }, - { - "type": "java.util.concurrent.DelayQueue" - }, - { - "type": "java.util.concurrent.Delayed" - }, - { - "type": "java.util.concurrent.Executor" - }, - { - "type": "java.util.concurrent.Executors" - }, - { - "type": "java.util.concurrent.LinkedBlockingQueue" - }, - { - "type": "java.util.concurrent.ThreadFactory" - }, - { - "type": "java.util.concurrent.ThreadLocalRandom" - }, - { - "type": "java.util.concurrent.TimeUnit" - }, - { - "type": "java.util.concurrent.atomic.AtomicLong" - }, - { - "type": "java.util.concurrent.atomic.AtomicReferenceArray" - }, - { - "type": "java.util.concurrent.locks.Lock" - }, - { - "type": "java.util.concurrent.locks.ReentrantLock" - }, - { - "type": "java.util.regex.Matcher" - }, - { - "type": "java.util.regex.Pattern" - }, - { - "type": "long[]" - }, - { - "type": "org.jline.nativ.CLibrary", - "jniAccessible": true, - "fields": [ - { - "name": "TCSADRAIN" - }, - { - "name": "TCSAFLUSH" - }, - { - "name": "TCSANOW" - }, - { - "name": "TIOCGWINSZ" - }, - { - "name": "TIOCSWINSZ" - } - ] - }, - { - "type": "org.jline.nativ.CLibrary$Termios", - "jniAccessible": true, - "fields": [ - { - "name": "SIZEOF" - }, - { - "name": "c_cc" - }, - { - "name": "c_cflag" - }, - { - "name": "c_iflag" - }, - { - "name": "c_ispeed" - }, - { - "name": "c_lflag" - }, - { - "name": "c_oflag" - }, - { - "name": "c_ospeed" - } - ] - }, - { - "type": "org.jline.nativ.CLibrary$WinSize", - "jniAccessible": true, - "fields": [ - { - "name": "SIZEOF" - }, - { - "name": "ws_col" - }, - { - "name": "ws_row" - }, - { - "name": "ws_xpixel" - }, - { - "name": "ws_ypixel" - } - ] - }, - { - "type": "org.jline.terminal.Terminal" - }, - { - "type": "org.jline.terminal.TerminalBuilder" - }, - { - "type": "org.jline.terminal.impl.PosixSysTerminal", - "methods": [ - { - "name": "writer", - "parameterTypes": [] - } - ] - }, - { - "type": "org.jline.terminal.impl.exec.ExecTerminalProvider", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "type": "org.jline.terminal.impl.jni.JniTerminalProvider", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "type": "org.jline.utils.InfoCmp$Capability" - }, - { - "type": "org.jline.utils.NonBlocking$NonBlockingInputStreamReader" - }, - { - "type": "org.jline.utils.NonBlockingReader", - "methods": [ - { - "name": "read", - "parameterTypes": [ - "long" - ] - } - ] - }, - { - "type": "org.jline.utils.Signals" - }, - { - "type": "org.objectweb.asm.Type" - }, - { - "type": "short[]" - }, - { - "type": "sun.misc.Signal", - "methods": [ - { - "name": "", - "parameterTypes": [ - "java.lang.String" - ] - }, - { - "name": "handle", - "parameterTypes": [ - "sun.misc.Signal", - "sun.misc.SignalHandler" - ] - } - ] - }, - { - "type": "sun.misc.SignalHandler", - "fields": [ - { - "name": "SIG_DFL" - } - ] - }, - { - "type": "sun.text.resources.cldr.FormatData" - }, - { - "type": "sun.text.resources.cldr.FormatData_en" - }, - { - "type": "sun.text.resources.cldr.FormatData_en_US" - }, - { - "type": { - "proxy": [ - "sun.misc.SignalHandler" - ] - } - } - ], - "resources": [ - { - "glob": "META-INF/maven/org.jline/jline-native/pom.properties" - }, - { - "glob": "META-INF/services/java.nio.charset.spi.CharsetProvider" - }, - { - "glob": "META-INF/services/org/jline/terminal/provider/exec" - }, - { - "glob": "META-INF/services/org/jline/terminal/provider/ffm" - }, - { - "glob": "META-INF/services/org/jline/terminal/provider/jansi" - }, - { - "glob": "META-INF/services/org/jline/terminal/provider/jna" - }, - { - "glob": "META-INF/services/org/jline/terminal/provider/jni" - }, - { - "glob": "charm/ansi/width.clj" - }, - { - "glob": "charm/ansi/width__init.class" - }, - { - "glob": "charm/components/help.clj" - }, - { - "glob": "charm/components/help__init.class" - }, - { - "glob": "charm/components/list.clj" - }, - { - "glob": "charm/components/list__init.class" - }, - { - "glob": "charm/components/paginator.clj" - }, - { - "glob": "charm/components/paginator__init.class" - }, - { - "glob": "charm/components/progress.clj" - }, - { - "glob": "charm/components/progress__init.class" - }, - { - "glob": "charm/components/spinner.clj" - }, - { - "glob": "charm/components/spinner__init.class" - }, - { - "glob": "charm/components/text_input.clj" - }, - { - "glob": "charm/components/text_input__init.class" - }, - { - "glob": "charm/components/timer.clj" - }, - { - "glob": "charm/components/timer__init.class" - }, - { - "glob": "charm/core.clj" - }, - { - "glob": "charm/core__init.class" - }, - { - "glob": "charm/input/handler.clj" - }, - { - "glob": "charm/input/handler__init.class" - }, - { - "glob": "charm/input/keys.clj" - }, - { - "glob": "charm/input/keys__init.class" - }, - { - "glob": "charm/input/mouse.clj" - }, - { - "glob": "charm/input/mouse__init.class" - }, - { - "glob": "charm/message.clj" - }, - { - "glob": "charm/message__init.class" - }, - { - "glob": "charm/program.clj" - }, - { - "glob": "charm/program__init.class" - }, - { - "glob": "charm/render/core.clj" - }, - { - "glob": "charm/render/core__init.class" - }, - { - "glob": "charm/render/screen.clj" - }, - { - "glob": "charm/render/screen__init.class" - }, - { - "glob": "charm/style/border.clj" - }, - { - "glob": "charm/style/border__init.class" - }, - { - "glob": "charm/style/color.clj" - }, - { - "glob": "charm/style/color__init.class" - }, - { - "glob": "charm/style/core.clj" - }, - { - "glob": "charm/style/core__init.class" - }, - { - "glob": "charm/style/layout.clj" - }, - { - "glob": "charm/style/layout__init.class" - }, - { - "glob": "charm/terminal.clj" - }, - { - "glob": "charm/terminal__init.class" - }, - { - "glob": "clojure/core.clj" - }, - { - "glob": "clojure/core/async.clj" - }, - { - "glob": "clojure/core/async/impl/buffers.clj" - }, - { - "glob": "clojure/core/async/impl/buffers__init.class" - }, - { - "glob": "clojure/core/async/impl/channels.clj" - }, - { - "glob": "clojure/core/async/impl/channels__init.class" - }, - { - "glob": "clojure/core/async/impl/concurrent.clj" - }, - { - "glob": "clojure/core/async/impl/concurrent__init.class" - }, - { - "glob": "clojure/core/async/impl/dispatch.clj" - }, - { - "glob": "clojure/core/async/impl/dispatch__init.class" - }, - { - "glob": "clojure/core/async/impl/exec/threadpool.clj" - }, - { - "glob": "clojure/core/async/impl/exec/threadpool__init.class" - }, - { - "glob": "clojure/core/async/impl/ioc_macros.clj" - }, - { - "glob": "clojure/core/async/impl/ioc_macros__init.class" - }, - { - "glob": "clojure/core/async/impl/mutex.clj" - }, - { - "glob": "clojure/core/async/impl/mutex__init.class" - }, - { - "glob": "clojure/core/async/impl/protocols.clj" - }, - { - "glob": "clojure/core/async/impl/protocols__init.class" - }, - { - "glob": "clojure/core/async/impl/timers.clj" - }, - { - "glob": "clojure/core/async/impl/timers__init.class" - }, - { - "glob": "clojure/core/async__init.class" - }, - { - "glob": "clojure/core/cache.clj" - }, - { - "glob": "clojure/core/cache__init.class" - }, - { - "glob": "clojure/core/memoize.clj" - }, - { - "glob": "clojure/core/memoize__init.class" - }, - { - "glob": "clojure/core/protocols.clj" - }, - { - "glob": "clojure/core/protocols__init.class" - }, - { - "glob": "clojure/core/server.clj" - }, - { - "glob": "clojure/core/server__init.class" - }, - { - "glob": "clojure/core__init.class" - }, - { - "glob": "clojure/core_deftype.clj" - }, - { - "glob": "clojure/core_deftype__init.class" - }, - { - "glob": "clojure/core_print.clj" - }, - { - "glob": "clojure/core_print__init.class" - }, - { - "glob": "clojure/core_proxy.clj" - }, - { - "glob": "clojure/core_proxy__init.class" - }, - { - "glob": "clojure/data/priority_map.clj" - }, - { - "glob": "clojure/data/priority_map__init.class" - }, - { - "glob": "clojure/datafy.clj" - }, - { - "glob": "clojure/datafy__init.class" - }, - { - "glob": "clojure/edn.clj" - }, - { - "glob": "clojure/edn__init.class" - }, - { - "glob": "clojure/genclass.clj" - }, - { - "glob": "clojure/genclass__init.class" - }, - { - "glob": "clojure/gvec.clj" - }, - { - "glob": "clojure/gvec__init.class" - }, - { - "glob": "clojure/instant.clj" - }, - { - "glob": "clojure/instant__init.class" - }, - { - "glob": "clojure/java/io.clj" - }, - { - "glob": "clojure/java/io__init.class" - }, - { - "glob": "clojure/main.clj" - }, - { - "glob": "clojure/main__init.class" - }, - { - "glob": "clojure/pprint.clj" - }, - { - "glob": "clojure/pprint/cl_format.clj" - }, - { - "glob": "clojure/pprint/cl_format__init.class" - }, - { - "glob": "clojure/pprint/column_writer.clj" - }, - { - "glob": "clojure/pprint/column_writer__init.class" - }, - { - "glob": "clojure/pprint/dispatch.clj" - }, - { - "glob": "clojure/pprint/dispatch__init.class" - }, - { - "glob": "clojure/pprint/pprint_base.clj" - }, - { - "glob": "clojure/pprint/pprint_base__init.class" - }, - { - "glob": "clojure/pprint/pretty_writer.clj" - }, - { - "glob": "clojure/pprint/pretty_writer__init.class" - }, - { - "glob": "clojure/pprint/print_table.clj" - }, - { - "glob": "clojure/pprint/print_table__init.class" - }, - { - "glob": "clojure/pprint/utilities.clj" - }, - { - "glob": "clojure/pprint/utilities__init.class" - }, - { - "glob": "clojure/pprint__init.class" - }, - { - "glob": "clojure/reflect.clj" - }, - { - "glob": "clojure/reflect/java.clj" - }, - { - "glob": "clojure/reflect/java__init.class" - }, - { - "glob": "clojure/reflect__init.class" - }, - { - "glob": "clojure/set.clj" - }, - { - "glob": "clojure/set__init.class" - }, - { - "glob": "clojure/spec/alpha.clj" - }, - { - "glob": "clojure/spec/alpha__init.class" - }, - { - "glob": "clojure/spec/gen/alpha.clj" - }, - { - "glob": "clojure/spec/gen/alpha__init.class" - }, - { - "glob": "clojure/string.clj" - }, - { - "glob": "clojure/string__init.class" - }, - { - "glob": "clojure/tools/analyzer.clj" - }, - { - "glob": "clojure/tools/analyzer/ast.clj" - }, - { - "glob": "clojure/tools/analyzer/ast__init.class" - }, - { - "glob": "clojure/tools/analyzer/env.clj" - }, - { - "glob": "clojure/tools/analyzer/env__init.class" - }, - { - "glob": "clojure/tools/analyzer/jvm.clj" - }, - { - "glob": "clojure/tools/analyzer/jvm/utils.clj" - }, - { - "glob": "clojure/tools/analyzer/jvm/utils__init.class" - }, - { - "glob": "clojure/tools/analyzer/jvm__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/add_binding_atom.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/add_binding_atom__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes/cleanup.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/cleanup__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes/constant_lifter.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/constant_lifter__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes/elide_meta.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/elide_meta__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes/emit_form.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/emit_form__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/analyze_host_expr.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/analyze_host_expr__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/annotate_host_info.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/annotate_host_info__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/annotate_loops.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/annotate_loops__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/annotate_tag.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/annotate_tag__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/box.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/box__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/classify_invoke.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/classify_invoke__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/constant_lifter.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/constant_lifter__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/emit_form.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/emit_form__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/fix_case_test.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/fix_case_test__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/infer_tag.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/infer_tag__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/validate.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/validate__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/validate_loop_locals.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/validate_loop_locals__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/validate_recur.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/validate_recur__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/warn_on_reflection.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/jvm/warn_on_reflection__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes/source_info.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/source_info__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes/trim.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/trim__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes/uniquify.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/uniquify__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes/warn_earmuff.clj" - }, - { - "glob": "clojure/tools/analyzer/passes/warn_earmuff__init.class" - }, - { - "glob": "clojure/tools/analyzer/passes__init.class" - }, - { - "glob": "clojure/tools/analyzer/utils.clj" - }, - { - "glob": "clojure/tools/analyzer/utils__init.class" - }, - { - "glob": "clojure/tools/analyzer__init.class" - }, - { - "glob": "clojure/tools/reader.clj" - }, - { - "glob": "clojure/tools/reader/default_data_readers.clj" - }, - { - "glob": "clojure/tools/reader/default_data_readers__init.class" - }, - { - "glob": "clojure/tools/reader/impl/commons.clj" - }, - { - "glob": "clojure/tools/reader/impl/commons__init.class" - }, - { - "glob": "clojure/tools/reader/impl/errors.clj" - }, - { - "glob": "clojure/tools/reader/impl/errors__init.class" - }, - { - "glob": "clojure/tools/reader/impl/inspect.clj" - }, - { - "glob": "clojure/tools/reader/impl/inspect__init.class" - }, - { - "glob": "clojure/tools/reader/impl/utils.clj" - }, - { - "glob": "clojure/tools/reader/impl/utils__init.class" - }, - { - "glob": "clojure/tools/reader/reader_types.clj" - }, - { - "glob": "clojure/tools/reader/reader_types__init.class" - }, - { - "glob": "clojure/tools/reader__init.class" - }, - { - "glob": "clojure/uuid.clj" - }, - { - "glob": "clojure/uuid__init.class" - }, - { - "glob": "clojure/version.properties" - }, - { - "glob": "clojure/walk.clj" - }, - { - "glob": "clojure/walk__init.class" - }, - { - "glob": "data_readers.clj" - }, - { - "glob": "data_readers.cljc" - }, - { - "glob": "examples/timer.clj" - }, - { - "glob": "examples/timer.cljc" - }, - { - "glob": "examples/timer__init.class" - }, - { - "glob": "org/jline/nativ/Linux/x86_64/libjlinenative.so" - }, - { - "glob": "org/jline/utils/capabilities.txt" - }, - { - "glob": "org/jline/utils/xterm-256color.caps" - }, - { - "glob": "user.clj" - } - ] -} diff --git a/docs/examples/resources/META-INF/native-image/timer/reflect-config.json b/docs/examples/resources/META-INF/native-image/timer/reflect-config.json deleted file mode 100644 index 98dd1cf..0000000 --- a/docs/examples/resources/META-INF/native-image/timer/reflect-config.json +++ /dev/null @@ -1,64 +0,0 @@ -[ - { - "name": "org.jline.terminal.impl.DumbTerminal", - "allDeclaredConstructors": true, - "allDeclaredMethods": true, - "allDeclaredFields": true - }, - { - "name": "org.jline.terminal.impl.AbstractTerminal", - "allDeclaredConstructors": true, - "allDeclaredMethods": true, - "allDeclaredFields": true - }, - { - "name": "org.jline.terminal.impl.AbstractPosixTerminal", - "allDeclaredConstructors": true, - "allDeclaredMethods": true, - "allDeclaredFields": true - }, - { - "name": "org.jline.terminal.impl.PosixSysTerminal", - "allDeclaredConstructors": true, - "allDeclaredMethods": true, - "allDeclaredFields": true - }, - { - "name": "org.jline.terminal.impl.jni.JniTerminalProvider", - "allDeclaredConstructors": true, - "allDeclaredMethods": true, - "allDeclaredFields": true - }, - { - "name": "org.jline.terminal.TerminalBuilder", - "allDeclaredConstructors": true, - "allDeclaredMethods": true, - "allDeclaredFields": true - }, - { - "name": "org.jline.terminal.spi.TerminalProvider", - "allDeclaredConstructors": true, - "allDeclaredMethods": true - }, - { - "name": "org.jline.nativ.JLineNativeLoader", - "allDeclaredConstructors": true, - "allDeclaredMethods": true, - "allDeclaredFields": true - }, - { - "name": "java.lang.Thread", - "allDeclaredConstructors": true, - "allDeclaredMethods": true - }, - { - "name": "java.io.PrintWriter", - "allDeclaredConstructors": true, - "allDeclaredMethods": true - }, - { - "name": "java.io.Writer", - "allDeclaredConstructors": true, - "allDeclaredMethods": true - } -] diff --git a/docs/examples/resources/META-INF/native-image/timer/resource-config.json b/docs/examples/resources/META-INF/native-image/timer/resource-config.json deleted file mode 100644 index 29e3929..0000000 --- a/docs/examples/resources/META-INF/native-image/timer/resource-config.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "resources": { - "includes": [ - {"pattern": "org/jline/.*"}, - {"pattern": ".*\\.properties$"}, - {"pattern": ".*\\.so$"}, - {"pattern": ".*\\.dylib$"}, - {"pattern": ".*\\.dll$"} - ] - } -} From f0e0d54f7eca4a3a34a0795691a9ae72e37f69bf Mon Sep 17 00:00:00 2001 From: Timo Kramer Date: Wed, 8 Apr 2026 14:57:49 +0200 Subject: [PATCH 5/6] refactor: remove mouse API changes (moved to fix/mouse-api branch) --- doc/examples/src/examples/sketch.clj | 128 --------------------------- src/charm/ansi/width.clj | 2 +- src/charm/input/mouse.clj | 2 +- src/charm/message.clj | 49 ---------- src/charm/program.clj | 20 ++--- src/charm/style/core.clj | 7 -- test/charm/message_test.clj | 40 +-------- 7 files changed, 8 insertions(+), 240 deletions(-) delete mode 100644 doc/examples/src/examples/sketch.clj diff --git a/doc/examples/src/examples/sketch.clj b/doc/examples/src/examples/sketch.clj deleted file mode 100644 index 58b1040..0000000 --- a/doc/examples/src/examples/sketch.clj +++ /dev/null @@ -1,128 +0,0 @@ -(ns examples.sketch - "A mouse-driven drawing pad. - Click/drag to draw, right-click to erase, scroll to change brush. - Demonstrates mouse interaction in charm.clj." - (:require - [charm.message :as msg] - [charm.program :as program] - [charm.style.core :as style] - [clojure.string :as str])) - -;; --------------------------------------------------------------------------- -;; Brushes -;; --------------------------------------------------------------------------- - -(def brushes ["█" "░" "▒" "▓" "●" "◆" "★" "♦" "╳" "○"]) - -;; --------------------------------------------------------------------------- -;; Styles -;; --------------------------------------------------------------------------- - -(def title-style - (style/style :fg style/magenta :bold true)) - -(def help-style - (style/style :fg style/white :faint true)) - -(def brush-style - (style/style :fg style/cyan :bold true)) - -;; --------------------------------------------------------------------------- -;; Init -;; --------------------------------------------------------------------------- - -(defn init [] - [{:canvas {} - :brush-idx 0 - :width 80 - :height 24 - :mouse-pos nil} - nil]) - -;; --------------------------------------------------------------------------- -;; Update -;; --------------------------------------------------------------------------- - -(defn- draw [canvas x y brush] - (assoc canvas [x y] brush)) - -(defn update-fn [state msg] - (cond - (or (msg/key-match? msg "q") - (msg/key-match? msg "ctrl+c")) - [state program/quit-cmd] - - (msg/key-match? msg "c") - [(assoc state :canvas {}) nil] - - (msg/window-size? msg) - [(assoc state - :width (:width msg) - :height (:height msg)) - nil] - - ;; Left click or drag: draw - (or (msg/left-click? msg) - (and (msg/motion? msg) (= :left (:button msg)))) - (let [brush (nth brushes (:brush-idx state))] - [(-> state - (update :canvas draw (:x msg) (:y msg) brush) - (assoc :mouse-pos [(:x msg) (:y msg)])) - nil]) - - ;; Right click or drag: erase - (or (msg/right-click? msg) - (and (msg/motion? msg) (= :right (:button msg)))) - [(-> state - (update :canvas dissoc [(:x msg) (:y msg)]) - (assoc :mouse-pos [(:x msg) (:y msg)])) - nil] - - ;; Track mouse position on any motion - (msg/motion? msg) - [(assoc state :mouse-pos [(:x msg) (:y msg)]) nil] - - ;; Scroll wheel: cycle brush - (msg/wheel-up? msg) - [(update state :brush-idx #(mod (dec %) (count brushes))) nil] - - (msg/wheel-down? msg) - [(update state :brush-idx #(mod (inc %) (count brushes))) nil] - - :else - [state nil])) - -;; --------------------------------------------------------------------------- -;; View -;; --------------------------------------------------------------------------- - -(defn view [state] - (let [{:keys [canvas brush-idx width height mouse-pos]} state - brush (nth brushes brush-idx) - ;; Reserve 2 lines for status bar - canvas-height (- height 2)] - (str - ;; Canvas area - (str/join - "\n" - (for [y (range 1 (inc canvas-height))] - (apply str - (for [x (range 1 (inc width))] - (get canvas [x y] " "))))) - "\n" - ;; Status bar - (style/render title-style "Sketch") - " " - (style/render brush-style (str "Brush: " brush)) - (when mouse-pos - (str " " (style/styled (str "(" (first mouse-pos) "," (second mouse-pos) ")") - :faint true))) - "\n" - (style/render help-style "click:draw right-click:erase scroll:brush c:clear q:quit")))) - -(defn -main [& _args] - (program/run {:init init - :update update-fn - :view view - :alt-screen true - :mouse :cell})) diff --git a/src/charm/ansi/width.clj b/src/charm/ansi/width.clj index e558079..3260ecc 100644 --- a/src/charm/ansi/width.clj +++ b/src/charm/ansi/width.clj @@ -1,4 +1,4 @@ -(ns ^:no-doc charm.ansi.width +(ns charm.ansi.width "Text width calculation for terminal display. Handles: diff --git a/src/charm/input/mouse.clj b/src/charm/input/mouse.clj index b64f8d1..26cb573 100644 --- a/src/charm/input/mouse.clj +++ b/src/charm/input/mouse.clj @@ -1,4 +1,4 @@ -(ns ^:no-doc charm.input.mouse +(ns charm.input.mouse "Mouse event parsing for terminal input. Supports: diff --git a/src/charm/message.clj b/src/charm/message.clj index 88bb093..293216f 100644 --- a/src/charm/message.clj +++ b/src/charm/message.clj @@ -165,52 +165,3 @@ "Check if shift modifier is set." [msg] (:shift msg false)) - -;; --------------------------------------------------------------------------- -;; Mouse Helpers -;; --------------------------------------------------------------------------- - -(defn click? - "Check if a mouse message is a click (press action)." - [msg] - (and (mouse? msg) (= :press (:action msg)))) - -(defn release? - "Check if a mouse message is a release." - [msg] - (and (mouse? msg) (= :release (:action msg)))) - -(defn motion? - "Check if a mouse message is motion (drag)." - [msg] - (and (mouse? msg) (= :motion (:action msg)))) - -(defn left-click? - "Check if a mouse message is a left click." - [msg] - (and (click? msg) (= :left (:button msg)))) - -(defn right-click? - "Check if a mouse message is a right click." - [msg] - (and (click? msg) (= :right (:button msg)))) - -(defn middle-click? - "Check if a mouse message is a middle click." - [msg] - (and (click? msg) (= :middle (:button msg)))) - -(defn wheel-up? - "Check if a mouse message is a wheel up event." - [msg] - (and (mouse? msg) (= :wheel-up (:action msg)))) - -(defn wheel-down? - "Check if a mouse message is a wheel down event." - [msg] - (and (mouse? msg) (= :wheel-down (:action msg)))) - -(defn wheel? - "Check if a mouse message is any wheel event." - [msg] - (or (wheel-up? msg) (wheel-down? msg))) diff --git a/src/charm/program.clj b/src/charm/program.clj index ef45909..30bc6b3 100644 --- a/src/charm/program.clj +++ b/src/charm/program.clj @@ -112,21 +112,11 @@ ;; Convert input event to message (let [m (cond (= :mouse (:type event)) - (let [raw-button (:button event) - wheel (case (int raw-button) - 4 :wheel-up 5 :wheel-down - 6 :wheel-left 7 :wheel-right - nil)] - (msg/mouse (if wheel wheel (:action event)) - (if wheel - :none - (case (int raw-button) - 0 :left 1 :middle 2 :right - :none)) - (:x event) (:y event) - :ctrl (:ctrl event) - :alt (:alt event) - :shift (:shift event))) + (msg/mouse (:button event) (:x event) (:y event) + :action (:action event) + :ctrl (:ctrl event) + :alt (:alt event) + :shift (:shift event)) (= :focus (:type event)) (msg/focus) diff --git a/src/charm/style/core.clj b/src/charm/style/core.clj index 2f78db6..0b6c558 100644 --- a/src/charm/style/core.clj +++ b/src/charm/style/core.clj @@ -274,13 +274,6 @@ (def join-horizontal l/join-horizontal) (def join-vertical l/join-vertical) -;; Text width utilities -(def string-width w/string-width) -(def truncate w/truncate) -(def pad-right w/pad-right) -(def pad-left w/pad-left) -(def strip-ansi w/strip-ansi) - ;; --------------------------------------------------------------------------- ;; Frame Size Calculation ;; --------------------------------------------------------------------------- diff --git a/test/charm/message_test.clj b/test/charm/message_test.clj index 67ce2c6..600bd15 100644 --- a/test/charm/message_test.clj +++ b/test/charm/message_test.clj @@ -78,42 +78,4 @@ (testing "mouse?" (is (msg/mouse? (msg/mouse :press :left 0 0))) - (is (not (msg/mouse? (msg/quit))))) - - (testing "click?" - (is (msg/click? (msg/mouse :press :left 10 20))) - (is (not (msg/click? (msg/mouse :release :none 10 20)))) - (is (not (msg/click? (msg/quit))))) - - (testing "release?" - (is (msg/release? (msg/mouse :release :none 10 20))) - (is (not (msg/release? (msg/mouse :press :left 10 20))))) - - (testing "motion?" - (is (msg/motion? (msg/mouse :motion :left 10 20))) - (is (not (msg/motion? (msg/mouse :press :left 10 20))))) - - (testing "left-click?" - (is (msg/left-click? (msg/mouse :press :left 10 20))) - (is (not (msg/left-click? (msg/mouse :press :right 10 20))))) - - (testing "right-click?" - (is (msg/right-click? (msg/mouse :press :right 10 20))) - (is (not (msg/right-click? (msg/mouse :press :left 10 20))))) - - (testing "middle-click?" - (is (msg/middle-click? (msg/mouse :press :middle 10 20))) - (is (not (msg/middle-click? (msg/mouse :press :left 10 20))))) - - (testing "wheel-up?" - (is (msg/wheel-up? (msg/mouse :wheel-up :none 10 20))) - (is (not (msg/wheel-up? (msg/mouse :wheel-down :none 10 20))))) - - (testing "wheel-down?" - (is (msg/wheel-down? (msg/mouse :wheel-down :none 10 20))) - (is (not (msg/wheel-down? (msg/mouse :press :left 10 20))))) - - (testing "wheel?" - (is (msg/wheel? (msg/mouse :wheel-up :none 10 20))) - (is (msg/wheel? (msg/mouse :wheel-down :none 10 20))) - (is (not (msg/wheel? (msg/mouse :press :left 10 20)))))) + (is (not (msg/mouse? (msg/quit)))))) From 8e66f2bafbee42c1173b73f1fa9b4df00b24ab8e Mon Sep 17 00:00:00 2001 From: Timo Kramer Date: Wed, 8 Apr 2026 15:00:03 +0200 Subject: [PATCH 6/6] fixup! refactor: remove mouse API changes (moved to fix/mouse-api branch) --- deps.edn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps.edn b/deps.edn index 5cf609f..60f4a1e 100644 --- a/deps.edn +++ b/deps.edn @@ -14,7 +14,7 @@ cider/cider-nrepl {:mvn/version "0.58.0"}} :main-opts ["-m" "nrepl.cmdline" "--middleware" "[cider.nrepl/cider-middleware]"]} - :examples {:extra-paths ["docs"]} + :examples {:extra-paths ["doc"]} :user {:extra-paths ["user"]}