Setting theme by time in emacs lisp - timer

I am trying to set the theme for Emacs but I have been experiencing some errors. Currently my code is:
;; theme
(defun set-theme-time ()
(let ((light 'modus-operandi)
(dark 'modus-vivendi))
(load-theme light t t)
(load-theme dark t t)
(run-at-time "8:00" nil
(lambda (light dark)
(disable-theme dark)
(enable-theme light)))
(run-at-time "17:00" nil
(lambda (light dark)
(disable-theme light)
(enable-theme dark)))
(message "Theme Loaded")))
(set-theme-time)
Everything in my config loads, and message does print Theme Loaded in the *Messages* buffer. However, the themes do not display, and after everything else has loaded I get this:
Error running timer: (wrong-number-of-arguments (lambda (light dark) (disable-theme dark) (enable-theme light)) 0) [2 times]
How can I fix this?
Edit: Here is the working code:
;; theme
(defun onoff (theme1 theme2)
(disable-theme theme1)
(enable-theme theme2))
(defun set-theme-time ()
(let ((light 'modus-operandi)
(dark 'modus-vivendi))
(load-theme light t t)
(load-theme dark t t)
(run-at-time "8:00" nil #'onoff dark light)
(run-at-time "17:00" nil #'onoff light dark)
(message "Theme Loaded")))
(set-theme-time)

It's not clear why you are using lambda or where you expect its arguments to come from. Did you perhaps mean something like this ...?
(defun set-theme-time ()
(let ((light 'modus-operandi)
(dark 'modus-vivendi)
(offon (lambda (off on) (disable-theme off) (enable-theme on))))
(load-theme light t t)
(load-theme dark t t)
(run-at-time "8:00" nil offon dark light)
(run-at-time "17:00" nil offon light dark)
(message "Theme Loaded")))
This is kind of clunky, though; perhaps it would make more sense for offon to be a separately defined named function which you could invoke by name #'offon.

Related

How to get SceneKit node placed over detected image to stay put as camera moves?

I'm very new to ARKit, and have built a small app based on Apple's "Detecting Images in an AR Experience" sample app. The sample app places a plane over the detected image; my app places an SCNBox at the center of it instead.
If the detected image is displayed on my monitor, I can move the phone all around and the box will stay fixed at the center of the image, which is what I want. If, however, the image is displayed on another iPhone, the box will move around as I move the phone running my app. Possibly due to the smaller screen size?
Here is my implementation of the didAdd delegate method:
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard let imageAnchor = anchor as? ARImageAnchor else { return }
updateQueue.async {
let cube = self.createCubeNode() // returns an SCNNode with SCNBox geometry
let position = SCNVector3(x: imageAnchor.transform.columns.3.x,
y: imageAnchor.transform.columns.3.y,
z: imageAnchor.transform.columns.3.z)
cube.worldPosition = position
self.sceneView.scene.rootNode.addChildNode(cube)
}
}
I found the answer. Instead of positioning and adding my cube node in didAdd, returning the node from nodeFor and letting the system place it completely fixes the problem. So I have removed the above code and replaced it with:
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
// make sure this is an image anchor, otherwise bail out
guard let _ = anchor as? ARImageAnchor else { return nil }
return self.createCubeNode() // returns an SCNNode with SCNBox geometry
}
I got this idea from a Hacking With Swift article: https://www.hackingwithswift.com/example-code/arkit/how-to-detect-images-using-arimagetrackingconfiguration

How to correctly wrap Google Closure UI Component as Rum Component

I would like to use Google Closure UI components from ClojureScript with the Rum/React library.
I started with goog.ui.DatePicker, but still cannot wrap it correctly. The code underneath renders the DatePicker once on component mount and at the right place, the event listener works and all is fine, except it needs the statically set id ("here") at the dom node to work which would be acceptable for one time hack, but not when I need to have the component wrapped and use several times on the same page/app.
(ns redux.components
(:require [rum.core :as r]
[cljs-time.core :as time]
[cljs-time.format :as tf]
[goog.dom :as dom]
[goog.ui.DatePicker :as goog-picker]
[goog.events :as goog-events]]))
(r/defcs +published-at < { :did-mount (fn [state]
(let [target-node (:r/ref state "here")
dp (goog.ui.DatePicker. nil goog.i18n.DateTimeSymbols_cs)]
(.listen dp (.. goog.ui.DatePicker -Events -CHANGE) #(println "new date is: " (tf/unparse (tf/formatter "YYYY-MM-dd")(time/to-default-time-zone (.. % -target getDate)))))
(.render dp (goog.dom/getElement "here")))
state) }
[]
[:div#here])
(r/defc app
[]
[:div
[:h1 "title"
(+published-at)]])
My further unsuccessful research
React documentation suggests that for integration with third-party DOM libraries one might need refs. Rum documentation describes how to do react refs from Rum. But the trouble is that React doc states that string refs are legacy and might be removed in future releases while Rum documentation does not cover callback based refs. I tried to guess how to combine both frameworks with string refs as well as callback refs, but neither one seems to work:
String based legacy approach
(r/defcs +published-at < { :did-mount (fn [state]
(let [target-node (:r/ref state "here")
dp (goog.ui.DatePicker. nil goog.i18n.DateTimeSymbols_cs)]
(.listen dp (.. goog.ui.DatePicker -Events -CHANGE) #(println (tf/unparse (tf/formatter "YYYY-MM-dd")(time/to-default-time-zone (.. % -target getDate)))))
(.render dp target-node))
state) }
[]
[:div
[:div { :ref "here" } ]])
This fails with error and the DatePicker is not even displayed:
Uncaught TypeError: opt_parentElement.insertBefore is not a function
at goog.ui.DatePicker.goog.ui.Component.render_ (component.js:705)
at goog.ui.DatePicker.goog.ui.Component.render (component.js:659)
at Function.<anonymous> (components.cljs?rel=1493075625598:123)
at Function.cljs.core.apply.cljs$core$IFn$_invoke$arity$3 (core.cljs:3694)
at cljs$core$apply (core.cljs:3676)
at util.cljc?rel=1492772300984:17
at core.cljs:2314
at Function.cljs.core.seq_reduce.cljs$core$IFn$_invoke$arity$3 (core.cljs:2314)
at cljs.core.LazySeq.cljs$core$IReduce$_reduce$arity$3 (core.cljs:3287)
at Function.cljs.core.reduce.cljs$core$IFn$_invoke$arity$3 (core.cljs:2358)
Callback base approach
(r/defcs +published-at < { :did-mount (fn [state]
(let [dp (goog.ui.DatePicker. nil goog.i18n.DateTimeSymbols_cs)]
(.listen dp (.. goog.ui.DatePicker -Events -CHANGE) #(println (tf/unparse (tf/formatter "YYYY-MM-dd")(time/to-default-time-zone (.. % -target getDate)))))
(.render dp (::put-date-here state)))
state) }
[state]
[:div
[:div { :ref #(assoc state ::put-date-here %) }]])
This renders functional DatePicker, but out of the component, at the end of the page.
You don't need :did-mount here, just render it right in the callback. This works fine for me:
(defn show-datepicker
[d]
(let [dp (goog.ui.DatePicker. nil goog.i18n.DateTimeSymbols_cs)]
(.listen dp (.. goog.ui.DatePicker -Events -CHANGE)
#(js/console.info
(.. % -target getDate)))
(.render dp d)))
[:div {:ref show-datepicker}]
If you need to tear down the datepicker then just check for (nil? d) in your show-datepicker. React will pass nil when the component unmounts.
PS: I wound't use cljs-time unless you really like big js output files.

Quiescent with devcards making cards go wonky

I'm using the quiescent library as my react wrapper. I was wanting to use devcards, and I was sort of hoping it would just work, even thought there isn't really a macro for quiescent like there is for om (i don't really know much about devcards yet).
Anyway, I got it all setup with figwheel and everything, and it's sort of working, but the cards ui is a little wacky:
First, here's what i think is the relative code:
(ns punt.core
(:require [quiescent.core :as q]
[quiescent.dom :as d])
(:require-macros [devcards.core :refer [defcard]]))
(def div1 (d/div {}
(d/h1 {} "hello")
(d/p {} "paragraph")
(d/h2 {} "second header")
(d/p {} "another paragraph")))
(def div2 (d/div {}
(d/h1 {} "a better hello")
(d/p {} "my favorite pargrauph")))
(q/defcomponent vertical-split [left right percentage]
(d/div {}
(d/div {:style {:float "left"
:width (str percentage "%")
:height "400px"}}
left)
(d/div {:style {:float "right"
:width (str (- 100 percentage) "%")
:height "400px"}}
right)))
(defcard fifty-fifty
"Description"
(vertical-split div1 div2 50))
(defcard fifty-fifty
(vertical-split div1 div2 80))
Now the content of the cards looks how I would expect, but the title bar of each card is extending a little crazy. Actually a picture is more helpful than explaining it, so here you go:
My diagnosis is that somehow devcards doesn't recognize the html that i made with quiescent, so it just doesn't put it in the card. Then it renders html for some reason, and then the next card is rendered, and i guess the title bar is programmed to extend all the way to the previous card, hence overlapping the stuff I made.
So guess my basic question is how to use quiescent with devcards.
The answer is so simple it's astounding, and it shows my lack of html and css knowledge. By making the container divs use overflow: auto they will expand the card to contain the actual content.

How to propagate text in input onChange with React/Om

As a React/Om newbie I am not sure if this issue is Om-specific.
I want to build a date entry component based on free text entry. It includes an <input> field where they can type, and a <p> displaying the parsed date (if it's valid).
I implemented it as:
(defn parse-date [e owner]
(let [text (.. e -target -value)]
(om/set-state! owner :parsed-date text)))
(defn date-entry [app owner]
(reify
om/IInitState
(init-state [_] {:parsed-date ""})
om/IRenderState
(render-state [this state]
(dom/div nil
(dom/input #js {:type "text"
:ref "date"
:id "new-date"
:onChange #(parse-date % owner)})
(dom/p nil (:parsed-date state))))))
Unfortunately, as soon as I plug this change handler in, it doesn't behave as expected. When I type a digit in the input field, I can see it appear in the input and the <p> next to it, but then it disappears from the input immediately.
I am able to work it around by putting the text on state:
(defn parse-date [e owner]
(let [text (.. e -target -value)]
(om/set-state! owner :parsed-date text)
(om/set-state! owner :text text)))
(defn date-entry [app owner]
(reify
om/IInitState
(init-state [_] {:parsed-date "" :text ""})
om/IRenderState
(render-state [this state]
(dom/div nil
(dom/input #js {:type "text"
:ref "date"
:id "new-date"
:onChange #(parse-date % owner)
:value (:text state)})
(dom/p nil (:parsed-date state))))))
However, I am surprised I had to do it. Is it really necessary? Can someone please explain what's going on here or point me to relevant docs? Why does plugging in a change handler calling set-state! swallow the event?
Yes it's necessary. Every time the state changes, DOM re-renders and clears your input's value. So if you have no :value in your :input's attributes, it will be cleared.
The reason for this is that when React.js starts diffing the real DOM, with the virtual one, it finds that there's some value in the real attribute, while there is none in the virtual DOM, and therefore it clears it, assuming that's what you want. You should always be explicit about what the DOM should look like (eg. your 2nd snippet).

Does JavaFX 8.0 TableView have a sort bug?

Java 8.0 x64, Win7 x64, Clojure, Emacs.
I'm doing some stuff in Clojure with TableView wherein I'm proxying TableCell so I can render and edit arbitrary things in it. The values are the fields of a map which is inside an atom. Code is below. It makes use of plenty of utility functions and macros to make this simpler, but you get the gist. The main thing is the management of the cell's graphic and text properties.
There is a keyboard handler which is attached to the ComboBox so it knows when the user presses ENTER, etc. This handler is removed on defocus from the cell, so we don't end up with multiple handlers in the object.
In this example I have three columns, one for the name of a field (A simple cell factory which only shows text and is not editable), one for the value (fancy cell factory), and one for the type (simple cell factory). The output, using some sample data, looks like this:
When I sort the table based on Value things seem to work fine, as follows:
Normally, when the keyboard handler triggers, it calls the cell's commitEdit function, which calls its TableCell superclass commitEdit. The TableView magic behind the scenes then calls the column's onEditCommit handler, which actually commits the edit to the database. After the superclass commitEdit returns, there is nothing left to do in the cell's commitEdit. The cell's updateItem is then automatically called by TableView which replaces the ComboBox with the normal contents of the cell.
PROBLEM
When I sort the table based on the Field column one or more times, or the Type column two or more times and try to edit something with a ComboBox (in this case the color selector), it takes an extra click to get the ComboBox to drop down, and the ENTER key doesn't work, specifically as follows:
CAUSE
In the broken case, the TableCell's superclass appears to return immediately and does not call column's onCommitEdit handler, nor does the cell's updateItem get called, so the cell is not rendered back to its normal non-editing state, ie, without the ComboBox.
Normal and broken cases look like this:
The debug text output in the normal case and broken case are shown here.
The weird thing is this problem sometimes appears with the non-color ComboBox as well (the sides field is has a ComboBox editor with numbers, for example).
So is this a bug in JavaFX TableView? Or am I doing something wrong?
(defn add-handlers!
"Adds common keyboard handler and focus listener to temporary editing graphic.
graphic is typically textfield or combo-box. cell is tablecell which
is being edited. getterfn is function to get value from graphic so
it can be commited to database."
[graphic cell getterfn]
(let [focus-listener (make-focus-change-listener cell getterfn)]
(println "adding focus and keyboard listener")
(add-listener! graphic :focused focus-listener)
(.setOnKeyPressed graphic (eventhandler [e] ;; here "cell" still refers to the tablecell
(condp = (.getCode e)
KeyCode/ENTER (do (println "ENTER pressed. Removing focus listener")
(remove-listener! graphic :focused focus-listener) ;; Prevent double-commit on defocus
(.commitEdit cell (getterfn)))
KeyCode/ESCAPE (do (println "ESC pressed. Removing focus listener")
(remove-listener! graphic :focused focus-listener) ;; Prevent double-commit on defocus
(.cancelEdit cell)) ;; Removes textfield
KeyCode/TAB (let [index (.. cell getTableRow getIndex)
next-column (get-next-column cell (not (.isShiftDown e)))]
(println "TAB pressed. Removing focus listener")
(remove-listener! graphic :focused focus-listener) ;; Prevent double-commit on defocus
(.commitEdit cell (getterfn))
(.edit (.getTableView cell) index next-column))
nil))))) ;; do nothing
(defn make-combobox
"Implements dropdown combobox. 'cell' is fancy table cell in
question. 'items' is list of things for dropdown, which can be
anything that the dropdown can render and choose as the final item"
[cell initvalue & [items]]
(let [cmb (jfxnode ComboBox (observable items))
cell-factory FANCY-LISTCELL-FACTORY
blank-cell (.call cell-factory nil)]
(doto cmb
(add-handlers! cell #(.getValue cmb))
(.setValue initvalue)
(.setButtonCell blank-cell)
(.setCellFactory cell-factory))))
(defn render-cell-with-item!
"Puts correct item in cell graphic and/or text property based on item
type. Additional arguments for editing such as drop-down, are
handled in the startEdit function; this function just renders the
cell when called by updateItem or cancelEdit."
[cell item]
(cond
(instance? Node item) (set-graphic-text! cell item nil) ;; for a graphic/Node item
(instance? Boolean item) (let [[var full-accesspath] (calc-full-accesspath cell)
cb (jfxnode CheckBox
:text (str item)
:selected item
:disable (not (mutable? var)))]
(.setEditable cell false)
(set-graphic-text! cell cb nil)
(when (mutable? var)
(uni-bind! (.selectedProperty cb) var full-accesspath)))
(instance? clojure.lang.PersistentVector item) (set-graphic-text! cell (Label. "Put vector editor here") nil)
(instance? Color item) (set-graphic-text! cell (make-color-box item) (color-map-inverse item))
;; All other types go here, presumably text types, so assume editable
:else (set-graphic-text! cell nil (si/to-normstr item)))) ;; else set underlying text
(def FANCY-TABLECELL-FACTORY
"The main callback interface which constructs the actual each cell
for arbitrary types. Assumes an editable cell for text representations."
(callback [column]
(proxy [TableCell] []
(updateItem [item empty]
(proxy-super updateItem item empty)
(when (not empty)
(render-cell-with-item! this item)))
(startEdit []
(proxy-super startEdit)
;; Change to appropriate graphic when editing
(println "in proxy's startEdit. Column commitHandler is" (.getOnEditCommit column))
(let [item (apply access-db (calc-full-accesspath this))
options (get-field-options this)] ;; could be nil ...
(if-let [combo-items (:combo-items options)] ;; ... so put as argument to :combo-items
(let [cmb (make-combobox this item combo-items)]
(set-graphic-text! this cmb nil)
(.requestFocus cmb)
(.show cmb)) ;; This makes drop-down appear without clicking twice.
(when (textish? item)
(let [tf (make-textfield-editor this)]
(set-graphic-text! this tf nil) ;; just set tf as graphic; leave existing text alone
(.requestFocus tf)
(.selectAll tf))))))
(cancelEdit []
;; CancelEdit gets called either by defocus or by ESC.
;; In any case, use the item currently in the database
;; for this cell and just render as in updateItem
(proxy-super cancelEdit)
(let [item (apply access-db (calc-full-accesspath this))]
(render-cell-with-item! this item)))
(commitEdit [value]
;; Nothing to do here. All commits happen either in the textField callback or in the column edit callback
(println "in cell's commitEdit, before super")
(proxy-super commitEdit value)
(println "in cell's commitEdit, after super")))))
(defn inner-table-view*
"Make inner table view for use by inspector-view and table-view"
[var accesspath columns]
(let [obslist (observable (var-snapshot var accesspath))]
(jfxnode TableView
:user-data {:var var ;; the actual var...
:accesspath accesspath } ;; ... and how to get to the displayed data
:items obslist
:columns columns
:editable (mutable? var))))
(defn inspector-view
"Takes plain map or atom/var/ref/agent of map and displays fields
and values in JFX TableView. Compound values (ie maps, vectors,
etc., for now are just displayed as their string value. If access
is supplied, assumes m is var/ref/atom and assigns appropriate
linkage between m and view contents. The topmost available var or
map is assigned to the TableView, and the accessor for each field is
assigned to each column."
[var & {:keys [accesspath field-options]}]
(let [ismutable (mutable? var)
field-col (jfxnode TableColumn "Field"
:cell-value-factory CELL-VALUE-FACTORY
:cell-factory SIMPLE-TABLECELL-FACTORY
:user-data {:accessfn key } ;; label-only option not relevant yet
:editable false
:sortable true)
value-col (jfxnode TableColumn "Value"
:cell-value-factory CELL-VALUE-FACTORY
:cell-factory FANCY-TABLECELL-FACTORY
:user-data {:accessfn val} ;; val is fn for accessing cell values from data item
:on-edit-start (eventhandler [e] (println "editing column " (.getOldValue e) (.getNewValue e)))
:on-edit-cancel (eventhandler [e] (println "canceling column with event" e))
:on-edit-commit (eventhandler [e] (do (println "column's on-edit-commit handler calling column-commit") (column-commit e)))
:editable ismutable
:comparator columnComparator)
type-col (jfxnode TableColumn "Type"
:cell-value-factory CELL-VALUE-FACTORY
:cell-factory SIMPLE-TABLECELL-FACTORY
:user-data {:accessfn #(type (val %))}
:editable false
:sortable true)
cols [field-col value-col type-col]
tv (inner-table-view* var accesspath cols)]
;; Add options to table's userData. This is for inspector-view
;; not table-view, so we don't put this in inner-table-view
;; function
(let [userdata (.getUserData tv)
newuserdata (conj userdata {:field-options field-options})]
(.setUserData tv newuserdata))
;; Add watches, use tv instance as key so we can remove it later
;; This gets called each time db is changed.
(if (mutable? var)
(add-watch var tv (fn [k r o n] ;; Key Ref Old New
(println "Inside KRON with new var" n)
;; Capture the existing sort order and type
;; Taken from http://stackoverflow.com/questions/11096353/javafx-re-sorting-a-column-in-a-tableview
(let [sort-order (vec (.getSortOrder tv)) ;; need to remember ObservableList<TableColumn> and vectorize or it gets reset from underneath us
sort-types (map #(.getSortType %) sort-order)
sortables (map #(.isSortable %) sort-order)]
;; Here we actually put the items into the tableview after the change
(.setItems tv (observable (var-snapshot var accesspath)))
;; Sort order is now empty up so we put back what was in it
(let [new-sort-order (.getSortOrder tv)] ;; get ObservableList<TableColumn>
(.setAll new-sort-order (into-array sort-order)) ;; reset the sort order based on what was there before
;; Assign sorting to each column
(doseq [col sort-order, sort-type sort-types, sortable sortables]
(.setSortType col sort-type)
(.setSortable col sortable)))))))
tv))
I found the problem, which was, of course, in my code.
Because JFX reuses cells, the editable property of the cell persists even when there are different contents rendered in the cell. In my case I had a boolean member of my databased which I rendered as a checkbox. The checkbox itself was clickable, but the cell in which it was rendered was not editable. When this cell got re-rendered after sort with a different item, the non-editing state persisted and screwed up the editing of the new item, which somehow led to the drop-down box not going away properly. Actually the bug showed up in non-combobox items too, such as for text edits, etc.
So the solution was to explicitly set the editable property of the cell for each item type that is rendered.

Resources