Normal instance method calls within a clojure doto - swing

I'm setting up a swing UI in clojure and have a block like:
(doto main-frame
(.setUndecorated true)
(.setExtendedState Frame/MAXIMIZED_BOTH)
(.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
(.setVisible true)
)
But now I want to call
(.setBackground (.getContentPane main-frame) Color/BLACK)
before I set the frame visible, is there a nicer way to do this than ending the doto and using the (.instanceMember instance args*) syntax?

If you really want a single doto, then maybe this will do:
(doto main-frame
(.setUndecorated true)
(.setExtendedState Frame/MAXIMIZED_BOTH)
(.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
(-> (.getContentPane) (.setBackground Color/BLACK))
(.setVisible true))
The above relies on the fact that doto is not confined to Java methods, it just inserts its first argument (evaluated) as first argument of every form that follows.
I'd go with ending the doto though as the above is not very readable. Alternatively, maybe just define a set-background-on-content-pane function (that obviously takes the main-frame) and use that in the doto:
(defn set-bg-on-frame [fr color] (.setBackground (.getContentPane fr) color))
(doto main-frame
.
.
.
(set-bg-on-frame Color/BLACK)
(.setVisible true))

Related

Turn vimscript key mapping into function

I am trying to make a function in vimscript that will activate on every cursor movement in visual mode, i.e. it will automatically highlight all the matches of the current visual selection.
The mapping from https://vi.stackexchange.com/questions/20077/automatically-highlight-all-occurrences-of-the-selected-text-in-visual-mode:
xnoremap <silent> <cr> "*y:silent! let searchTerm = '\V'.substitute(escape(#*, '\/'), "\n", '\\n', "g") <bar> let #/ = searchTerm <bar> echo '/'.#/ <bar> call histadd("search", searchTerm) <bar> set hls<cr>
works perfectly for me but I am failing to implement it into function. This is what I tried:
function! HighlightVisual(mode)
if mode()=~#"^[vV\<C-v>]"
call feedkeys('"*y')
let searchTerm = '\V'.substitute(escape(#*, '\/'), "\n", '\\n', "g")
let #/ = searchTerm
echo '/'.#/
call histadd("search", searchTerm)
set hls
endif
endfunction
autocmd CursorMoved * call HighlightVisual(mode())
However, it is not working.
What am I doing wrong? I think the function is terminated each time a call is invoked but have no idea how to workaround that.
I have made it work. Firstly, I found from https://vi.stackexchange.com/questions/28404/vim-does-not-call-functions-correctly-when-wrapped-in-another-function that "Vim doesn't like updating Screen too often" so redraw was necessary after set hls. And secondly, y was forcing normal mode and gv was moving cursor triggering the autocmd CursorMoved inside the function thus making an infinite loop. I made a workaround by set eventignore=CursorMoved and resetting it back at the end of function. I am saving selected word to register h (as in highlight) but you can choose any by changing "hy and #h. Moreover, I added highlight toggle when not needed. So, if somebody wants to use the feature of automatically highlighting visual matches, here is the code:
function! HighlightVisual(mode)
if mode()=~#"^[vV\<C-v>]"
set eventignore=CursorMoved
normal "hy
normal gv
let searchTerm = '\V'.substitute(escape(#h, '\/'), "\n", '\\n', "g")
let #/ = searchTerm
call histadd("search", searchTerm)
set hls
redraw
set eventignore=""
endif
endfunction
autocmd CursorMoved * :call HighlightVisual(mode())
vnoremap <silent> <ESC> :<C-u>set nohlsearch<CR>
; just copy-paste it in your .vimrc/init.vim.
Big thanks to trusktr as I used his answer in https://vi.stackexchange.com/questions/20077/automatically-highlight-all-occurrences-of-the-selected-text-in-visual-mode to build my function I wanted for sooo long.
Happy coding!

Render html to racket gui

I'm trying to write a WYSIWYG text editor that allows me to write text in the top window, and have the resulting scribble text rendered in the bottom window. I figured the way I would do this would be to call scribble myfile.rkt in the background periodically, and then render the resulting output to a bottom screen using render-html-to-text. I'm having some trouble getting the render to work. Based on the documentation I need
in : input-port?
dest : (is-a? html-text<%>)
load-img? : any/c
eval-rkt? : any/c
The relevant parts of my script look like this
#lang racket/gui
(require racket/os racket/runtime-path "init.rkt"
browser/htmltext)
(require browser)
(define f (new frame% [label (~a "Dremacs" "#" (gethostname))]
[width 960]
[height 540]))
(define new-cnv (new cnv% [parent f]))
(send t insert ";; This buffer is for text that is not saved, and for Lisp evaluation.
;; To create a file, visit it with C-x C-f and enter text in its buffer.")
(send new-cnv set-editor t)
(define html-renderer%
(interface (html-text<%>)))
(define viewer (new panel%
[parent f]
[min-width 300]
[min-height 300]))
(render-html-to-text (open-input-file "TODO.html") html-renderer% #t #t)
(send f show #t)
But I get the error
render-html-to-text: expects argument of type <html-text<%> object>; given: '(#<input-port:/home/diego/repos/dremacs/dremacs/TODO.html> #<interface:html-renderer%>)
context...:
/usr/share/racket/pkgs/drracket/browser/htmltext.rkt:61:0: render-html-to-text
"/home/diego/repos/dremacs/dremacs/editor.rkt": [running body]
temp37_0
And I'm not sure what I'm doing wrong. Could anyone help?
The html-renderer% is not created correctly.
Use html-text-mixin to turn a text% into something that handles html-text.
But ... don't expect too much from the html-renderer.
It's old and doesn't support stylesheets.
Back in the day it was used to display documentation for DrRacket.

"Autosave" Functionality in ClojureScript

I'd like to add an "autosave" feature to a Reagent form in a ClojureScript function. In Clojure, I usually make something out of a ScheduledExecutorService. Since that isn't available in ClojureScript, I came up with the following.
(def delay-handle (atom nil))
(defn clear-autosave-delay! []
(.clearTimeout js/window #delay-handle))
(defn start-autosave-delay!
[doc-save-fn delay-ms page-map-atom]
(reset! delay-handle (.setTimeout js/window doc-save-fn delay-ms page-map-atom)))
(defn change-watcher!
[doc-save-fn page-map-atom]
(let [delay (* 1000 (get-in #page-map-atom [:options :editor_autosave_interval]))]
(when (pos? delay)
(clear-autosave-delay!)
(start-autosave-delay! doc-save-fn delay page-map-atom))))
I put the change-watcher! function in the Reagent :on-change handlers for the input controls. Whenever a change occurs, it resets the delay. If the delay expires, the doc-save-fn is called to do the save.
It seems to work Ok, but isn't very "Clojuresque." Is there a more idiomatic way to write this?​
Use debouncer for this issue. It's pretty simple and does same
(goog.functions.debounce auto-save-action 1000)

How can I bind the schematic variable ?case in a rule for proof by cases?

I would like to define a rule for proof by cases, to be used with proof (cases rule: <rule-name>). I managed to use the case_names and consumes parameters, but I did not manage to bind the schematic variable ?case, so that, inside a case of a proof using my rule, one can write show ?case .... How do I bind it?
Concretely: I have the Mizar-inspired notion of a trivial set, i.e. empty or singleton set. I would like to prove properties of trivial sets by empty vs. singleton case analysis. So far I have:
definition trivial where "trivial x = (x ⊆ {the_elem x})"
lemma trivial_cases [case_names empty singleton, consumes 1]:
assumes "trivial X"
assumes empty: "P {}"
and singleton: "⋀ x . X = {x} ⟹ P {x}"
shows "P X"
using assms unfolding trivial_def by (metis subset_singletonD)
and I can make use of this as follows:
notepad
begin
fix Q
fix X::"'a set"
have "trivial X" sorry
then have "Q X"
proof (cases rule: trivial_cases)
case empty
show "Q {}" sorry
next
case (singleton x)
show "Q {x}" sorry
qed
end
But I cannot use show ?case. If I try, it gives me the error message "Unbound schematic variable: ?case". print_cases inside the proof outputs the following:
cases:
empty:
let "?case" = "?P {}"
singleton:
fix x_
let "?case" = "?P {x_}"
assume "X = {x_}"
Which suggests that it doesn't work because ?P is not bound to trivial.
BTW: The full context in which I am using this can be seen at https://github.com/formare/auctions/blob/master/isabelle/Auction/SetUtils.thy.
As Joachim already mentioned, unlike induct, the cases method does not bind the schematic variable ?case. I would say the "canonical" way of conducting case analysis (as a proof method) conforms to this setup, since typically only different assumptions -- which taken together are exhaustive -- are considered, whereas the conclusion stays the same (abbreviated by ?thesis in Isabelle) throughout the different cases. I would set up your trivial_cases as follows:
lemma trivial_cases [consumes 1, case_names empty singleton]:
assumes "trivial X" and "X = {} ⟹ P" and "⋀x . X = {x} ⟹ P"
shows "P"
using assms by (auto simp: trivial_def)
Then you can use it like
notepad
begin
fix P and X :: "'a set"
have "trivial X" sorry
then have "P X"
proof (cases rule: trivial_cases)
case empty
then show ?thesis sorry
next
case (singleton x)
then show ?thesis sorry
qed
end
where the simplifier or explicit unfolding takes care of specializing X to {} and {x}, respectively.
Side Note: You can further tune trivial_cases by adding the attribtue cases pred: trivial. Then, whenever trivial ?X is the major assumption fed to cases, the rule trivial_cases is used implicitly, i.e., you can do the following
have "trivial X" sorry
then have "P X"
proof (cases)
in the above proof.

Image Processing, extending JPanel and Simulating Classes in Clojure

there! I'm building an image-processing application in swing/clojure, and right now I need to develop an image panel in which I can click and compute data. Thanks to coobird, I now have a good idea on how to do it in Java, but I still don't get many issues on its integration with Clojure.
Let's take a look at how coobird suggested me doing. First, we should extend a class in Java. In clojure, we do this with the proxy macro, so we'd have something like this:
(def painting-panel
(proxy [JPanel] []))
The next step is to create the class constructor and set some variables.
I can define functions after the second argument of proxy, but how can I create the constructor? Is painting-panel the name of this class (therefore the name of the function I should create)?
How can I deal with class variables? Should I define them with a let, like I did?
Are this and super available for me to use, like I did below?
(def painting-panel
(let [background-image (Image.)
point-clicked (Point.)]
(proxy [JPanel] []
(paintComponent [g]
(do ((.paintComponent super) g)
(doto g
(.drawImage background-image 0 0 nil)
(.fillRect (.x point-clicked) (.y point-clicked) 1 1))))
(painting-panel []; constructor?
((.addMouseListener this)
(proxy [MouseAdapter] []
(mouseClicked [e]
(do
(def point-clicked (.getPoint e))
(.repaint this)))))))))
Suggestions and code corrections are also welcome!
Thank you!
proxy actually creates an instance tada! You don't need to create a constructor.
Yes, but consider using a clojure ref instead. Also using def like that on the second last line is nasty! it creates a global binding for point-clicked when your logic relies on the lexically scoped one created by let.
(proxy-super paintComponent g), and yes "this" is available
This works for me:
(let [click (ref nil)
panel (proxy [javax.swing.JPanel] []
(paintComponent [g]
(proxy-super paintComponent g)
(.drawImage g (.getImage
(javax.swing.ImageIcon. "play.png"))
0 0 (.getWidth this) (.getHeight this) nil)
(if #click
(.fillRect g (:x #click) (:y #click) 10 10))))]
(.addMouseListener panel
(proxy [java.awt.event.MouseAdapter] []
(mouseClicked [e]
(let [p (.getPoint e)]
(dosync (ref-set click {:x (.x p), :y (.y p)})))
(javax.swing.SwingUtilities/invokeLater #(.repaint panel)))))
(doto (javax.swing.JFrame.)
(.setContentPane panel)
(.setSize 200 200)
(.show)))