I wanted to wrap the jkeymaster library in a Clojure wrapper (for my own use, but perhaps also to save others some time). I'm just learning Clojure so I'm still not quite sure what "idiomatic libraries/APIs" look like. In Ruby, I would have created an object with methods, but in one of the clojure books they recommended letting users manage state themselves, so I have function that creates a provider, and this provider must then be passed to the register function.
Here's first an example of usage:
(ns keymaster.core
(:require [keymaster.keymaster :as km]))
(defn -main
"I don't do a whole lot ... yet."
[& args]
(km/register (km/provider) "control shift 1" #(println "hi")))
And here is the full text of the "library".
(ns keymaster.keymaster
(:gen-class)
(:use (com.tulskiy.keymaster.common)))
(defn provider []
"Gets and initiates a keymaster provider, which must be passed to register to register shortcuts"
(let [provider (com.tulskiy.keymaster.common.Provider/getCurrentProvider true)]
(.init provider)
provider))
(defn- conv-keystroke [x]
"Takes keystroke in the form \"control shift 1\" and returns a Keystroke class"
(javax.swing.KeyStroke/getKeyStroke x))
(defn- conv-listener [f]
"Takes a function with one argument, which will get passed the keycode, and creates a listener
Todo: How to accept a function with or without a parameter to accept hotKey?"
(proxy [com.tulskiy.keymaster.common.HotKeyListener] [] (onHotKey [hotKey] (f))))
(defn register
[provider shortcut listener]
"Registers a shortcut on provider, which will trigger listener (with one argument)"
(let [k (conv-keystroke shortcut)
l (conv-listener listener)]
(.register provider k l)))
In addition to any general style feedback, both about the coding, and the design of the API, I'm also wondering if there is any way to have conv-listener accept either a 0 or 1-arity function. Right now I made the choice of accepting a 0-arity function, but if someone wanted to pass a 1-arity function, where the first argument would be the name of the keycode called (hotKey
), which I would call with (f hotKey)
, I would have to rewrite... Possible to allow both? (1-arity is inconvenient for anonymous functions where we really don't need it - which I suspect is most of the time, since we can bind different hotkeys to different listeners).