Skip to content
This repository has been archived by the owner on Oct 21, 2022. It is now read-only.

Commit

Permalink
Merge pull request #1955 from LightTable/add-docstrings
Browse files Browse the repository at this point in the history
Add docstrings per #1715
  • Loading branch information
cldwalker committed Aug 27, 2015
2 parents 8e8d20a + c247b33 commit 1d9dd0c
Show file tree
Hide file tree
Showing 68 changed files with 290 additions and 53 deletions.
25 changes: 22 additions & 3 deletions src/lt/macros.clj
Original file line number Diff line number Diff line change
@@ -1,18 +1,35 @@
(ns lt.macros
"Macros used across LT"
(:require [clojure.walk :as walk]))

(defn- namify [type keyword]
(symbol (str "__" type "__" (.replace (name keyword) "." "__DOT__"))))

(defmacro behavior [name & {:keys [reaction] :as r}]
(defmacro behavior
"Define a behavior with a unique namespaced keyword and multiple key value pairs.
Keys are:
* :reaction (required) - Function to invoke when behavior is called.
First arg is object behavior is attached to
* :triggers (required) - Set of keyword triggers that trigger behavior
* :desc - Brief description of behavior
* :type - When set to :user, shows up in hints. Not enabled by default
* :params - Vector of maps describing behavior args. Each map contains required :label key
and optional keys of :type (:string, :number or :list), :items and :example
* :throttle - Number of ms to throttle reaction fn
* :debounce - Number of ms to debounce reaction fn"
[name & {:keys [reaction] :as r}]
(if (and (seq? reaction) (= 'fn (first reaction)))
(let [[_ args & body] reaction]
`(do
(defn- ~(namify "BEH" name) ~args ~@body)
(lt.object/behavior* ~name ~@(apply concat (assoc r :reaction (namify "BEH" name))))))
`(lt.object/behavior* ~name ~@(apply concat r))))

(defmacro defui [sym params hiccup & events]
(defmacro defui
"Define a UI element for given hiccup data and key-value pairs
of events for element"
[sym params hiccup & events]
`(defn ~sym ~params
(let [e# (crate.core/html ~hiccup)]
(doseq [[ev# func#] (partition 2 ~(vec events))]
Expand Down Expand Up @@ -68,7 +85,9 @@
`(let [~start (.getTime (js/Date.))]
~@body)))

(defmacro background [func]
(defmacro background
"Register given func to run on background thread"
[func]
`(lt.objs.thread/thread*
(fn ~(gensym "tfun") []
(let [orig# (js/argsArray js/arguments)
Expand Down
102 changes: 83 additions & 19 deletions src/lt/object.cljs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
(ns lt.object
"Define core of BOT architecture and provide fns for manipulating objects,
behaviors and tags"
(:refer-clojure :exclude [set!])
(:require [crate.core :as crate]
[clojure.set :as set]
Expand All @@ -9,13 +11,34 @@
[lt.util.js :refer [throttle debounce]])
(:require-macros [lt.macros :refer [behavior with-time aloop]]))

(def obj-id (atom 0))
(def instances (atom (sorted-map)))
(def behaviors (atom {}))
(def object-defs (atom {}))
(def tags (atom {}))
(def negated-tags (atom {}))
(def ^{:dynamic true} *behavior-meta* nil)
;; HEART of BOT Architecture!
(def obj-id
"Counter to guarantee unique object ids"
(atom 0))

(def instances
"Map of object ids to objects created by object/create"
(atom (sorted-map)))

(def behaviors
"Map of behavior names to behaviors created by macros/behavior"
(atom {}))

(def object-defs
"Map of object template keys to template maps created by object/object*"
(atom {}))

(def tags
"Map of tags to associated lists of behaviors"
(atom {}))

(def negated-tags
"Map of tags to dissociated lists of behaviors e.g. :-behavior"
(atom {}))

(def ^{:dynamic true} *behavior-meta*
"Metadata of current behavior set during raise and raise-reduce"
nil)

(defn add [obj]
(swap! object-defs assoc (::type obj) obj))
Expand Down Expand Up @@ -118,7 +141,9 @@
(safe-report-error e)
)))))

(defn raise [obj k & args]
(defn raise
"Invoke object's behavior fns for given trigger. Args are passed to behavior fns"
[obj k & args]
(let [reactions (-> @obj :listeners k)]
(raise* obj reactions args k)))

Expand Down Expand Up @@ -158,10 +183,14 @@
(add obj)
obj)

(defn instances-by-type [type]
(defn instances-by-type
"Return all objects for given type (template name)"
[type]
(filter #(= type (::type (deref %))) (vals @instances)))

(defn merge! [obj m]
(defn merge!
"Merge map into object"
[obj m]
(when (and m (not (map? m)))
(throw (js/Error. (str "Merge requires a map: " m))))
(swap! obj merge m))
Expand All @@ -188,7 +217,18 @@
(raise inst :redef))
id))

(defn object* [name & r]
(defn object*
"Create object template (type) given keyword name and key-value pairs.
These pairs serve as default attributes for an object. Following keys
have special meaning:
* :behaviors - Set of object's behaviors
* :tags - Set of object's tags
* :triggers - Set of object's triggers
* :init - Init fn called when object is created. Fn's return value
is hiccup html content and saved to :content
* :listeners (internal) - Map of triggers to vectors of behaviors"
[name & r]
(-> (apply make-object* name r)
(store-object*)
(handle-redef)))
Expand Down Expand Up @@ -218,7 +258,10 @@
(wrap-debounce)
(store-behavior*)))

(defn raise-reduce [obj k start & args]
(defn raise-reduce
"Reduce over invoked object's behavior fns for given trigger. Start
is initial value for reduce and any args are passed to behavior fn"
[obj k start & args]
(let [reactions (-> @obj :listeners k)]
(reduce (fn [res cur]
(let [func (:reaction (->behavior cur))
Expand All @@ -237,7 +280,9 @@

(declare create)

(defn update! [obj & r]
(defn update!
"Update object with update-in with [:key], fn and args"
[obj & r]
(swap! obj #(apply update-in % r)))

(defn assoc-in! [obj k v]
Expand All @@ -251,10 +296,15 @@
(deref? o) o
:else (@instances o)))

(defn ->content [obj]
(defn ->content
"Return DOM content associated with object"
[obj]
(:content @obj))

(defn destroy! [obj]
(defn destroy!
"Destroy object by calling its :destroy trigger, removing it from
cache and removing associated DOM content"
[obj]
(when-let [inst (->inst obj)]
(raise inst :destroy)
(swap! instances dissoc (->id inst))
Expand All @@ -266,7 +316,15 @@
(swap! instances assoc (::id @inst) inst)
inst)

(defn create [obj-name & args]
(defn create
"Create object given keyword name of object template or an object template
and key-value pairs. See object* for special keys.
During object creation the following happens to object in order:
* :init fn is called with given args
* :object.instant trigger is raised
* :init trigger is raised"
[obj-name & args]
(let [obj (if (keyword? obj-name)
(@object-defs obj-name)
obj-name)
Expand Down Expand Up @@ -309,11 +367,15 @@
def|name
(@object-defs def|name)))

(defn by-id [id]
(defn by-id
"Find object by its unique numerical id"
[id]
(when id
(@instances id)))

(defn by-tag [tag]
(defn by-tag
"Find objects that have given tag"
[tag]
(sort-by (comp ::id deref)
(filter #(when-let [ts (:tags (deref %))]
(ts tag))
Expand Down Expand Up @@ -344,7 +406,9 @@
(raise obj ::tags-removed ts)
obj))

(defn tag-behaviors [tag behs]
(defn tag-behaviors
"Associate behaviors to given tag and refresh objects with given tag"
[tag behs]
(swap! tags update-in [tag] #(reduce conj
(or % '())
behs))
Expand Down
1 change: 1 addition & 0 deletions src/lt/objs/animations.cljs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
(ns lt.objs.animations
"Manage (de)activating animations"
(:require [lt.object :as object]
[lt.util.dom :as dom])
(:require-macros [lt.macros :refer [behavior]]))
Expand Down
2 changes: 2 additions & 0 deletions src/lt/objs/app.cljs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
(ns lt.objs.app
"Provide app object which manages app startup, app shutdown and
window related features"
(:require [lt.object :as object]
[lt.objs.platform :as platform]
[lt.objs.command :as cmd]
Expand Down
1 change: 1 addition & 0 deletions src/lt/objs/bottombar.cljs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
(ns lt.objs.bottombar
"Provide bottombar object and associated behaviors"
(:require [lt.object :as object]
[lt.objs.tabs :as tabs]
[lt.objs.animations :as anim]
Expand Down
1 change: 1 addition & 0 deletions src/lt/objs/browser.cljs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
(ns lt.objs.browser
"Provide browser object which wraps around Electron's webview"
(:require [lt.object :as object]
[lt.objs.tabs :as tabs]
[lt.objs.command :as cmd]
Expand Down
1 change: 1 addition & 0 deletions src/lt/objs/cache.cljs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
(ns lt.objs.cache
"Provide cache which persists to disk and thus across application reboots"
(:require [lt.object :as object]
[lt.objs.files :as files]
[cljs.reader :as reader])
Expand Down
2 changes: 2 additions & 0 deletions src/lt/objs/canvas.cljs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
(ns lt.objs.canvas
"Provide canvas object which contains the primary div of the UI: #canvas.
Children divs are #multi (tabs), #side, #right-bar and #bottombar"
(:refer-clojure :exclude [rem])
(:require [lt.object :as object]
[lt.objs.context :as ctx]
Expand Down
2 changes: 2 additions & 0 deletions src/lt/objs/cli.cljs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
(ns lt.objs.cli
"Provide behaviors for commandline parsing and opening files from
commandline or file manager"
(:require [lt.object :as object]
[lt.objs.app :as app]
[lt.objs.files :as files]
Expand Down
2 changes: 2 additions & 0 deletions src/lt/objs/clients.cljs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
(ns lt.objs.clients
"Provide clients object for managing multiple types of clients e.g. browser
or Clojure and their connections"
(:refer-clojure :exclude [send])
(:require [lt.object :as object]
[lt.util.js :refer [wait]]
Expand Down
2 changes: 2 additions & 0 deletions src/lt/objs/clients/devtools.cljs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
(ns lt.objs.clients.devtools
"Provide devtools client for interacting with Chromium's remote debugging
protocol - https://developer.chrome.com/devtools/docs/debugger-protocol"
(:refer-clojure :exclude [send])
(:require [cljs.reader :as reader]
[lt.object :as object]
Expand Down
1 change: 1 addition & 0 deletions src/lt/objs/clients/local.cljs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
(ns lt.objs.clients.local
"Provide local client for connecting to LT"
(:refer-clojure :exclude [send])
(:require [cljs.reader :as reader]
[lt.object :as object]
Expand Down
1 change: 1 addition & 0 deletions src/lt/objs/clients/tcp.cljs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
(ns lt.objs.clients.tcp
"Define tcp server for use with language plugins"
(:refer-clojure :exclude [send])
(:require [cljs.reader :as reader]
[lt.object :as object]
Expand Down
1 change: 1 addition & 0 deletions src/lt/objs/clients/ws.cljs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
(ns lt.objs.clients.ws
"Define websocket server for use with language plugins e.g. JavaScript"
(:refer-clojure :exclude [send])
(:require [cljs.reader :as reader]
[lt.object :as object]
Expand Down
10 changes: 9 additions & 1 deletion src/lt/objs/command.cljs
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
(ns lt.objs.command
"Provide command manager and command related fns"
(:require [lt.object :as object]))

(declare manager)

(def required-keys #{:command :desc :exec})

(defn command [cmd]
(defn command
"Define a command given a map with the following keys:
* :command (required) - Unique keyword name for command
* :desc (required) - Brief description of command
* :exec (required) - Function to invoke when command is called
* :hidden - When true, command is hidden from command bar. Not set by default"
[cmd]
(assert (every? cmd required-keys)
(str "Command doesn't have required keys: " required-keys))
(object/update! manager [:commands] assoc (:command cmd) cmd)
Expand Down
1 change: 1 addition & 0 deletions src/lt/objs/connector.cljs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
(ns lt.objs.connector
"Provide client-selector object for UI and behaviors to choosing a client"
(:require [lt.object :as object]
[lt.objs.canvas :as canvas]
[lt.objs.popup :as popup]
Expand Down
2 changes: 2 additions & 0 deletions src/lt/objs/console.cljs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
(ns lt.objs.console
"Provide console object for logging to file and displaying log messages
in bottom bar"
(:require [lt.object :as object]
[lt.objs.app :as app]
[lt.objs.files :as files]
Expand Down
3 changes: 3 additions & 0 deletions src/lt/objs/context.cljs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
(ns lt.objs.context
"Provide context object which manages temporary contexts LT can get in.
An object can be associated with a context which is useful for keeping track
of current tabset or browser"
(:require [lt.object :as object])
(:require-macros [lt.macros :refer [behavior]]))

Expand Down
2 changes: 2 additions & 0 deletions src/lt/objs/deploy.cljs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
(ns lt.objs.deploy
"Provide behaviors to check for app updates and fns for downloading
and unpacking downloaded assets"
(:require [lt.object :as object]
[lt.objs.clients :as clients]
[lt.objs.files :as files]
Expand Down
1 change: 1 addition & 0 deletions src/lt/objs/dev.cljs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
(ns lt.objs.dev
"Provide commands for LT developer"
(:require [lt.object :as object]
[lt.util.js :refer [wait ]]
[lt.objs.cache :as cache]
Expand Down
1 change: 1 addition & 0 deletions src/lt/objs/dialogs.cljs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
(ns lt.objs.dialogs
"Provide Electron-based dialogs"
(:require [lt.object :as object]
[lt.util.dom :as dom]
[lt.objs.app :as app])
Expand Down
1 change: 1 addition & 0 deletions src/lt/objs/docs.cljs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
(ns lt.objs.docs
"Provide command and behavior(s) to see LT documentation"
(:require [lt.object :as object]
[lt.objs.command :as cmd]
[lt.objs.tabs :as tabs])
Expand Down
2 changes: 2 additions & 0 deletions src/lt/objs/document.cljs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
(ns lt.objs.document
"Provide document object for wrapping CodeMirror documents. See
http://codemirror.org/doc/manual.html#api_doc for more"
(:require [lt.object :as object]
[lt.objs.files :as files]
[lt.objs.popup :as popup])
Expand Down

0 comments on commit 1d9dd0c

Please sign in to comment.