move command state into per-frame table
lots of dependent changes here, unfortunately - get rid of Buffer.current (it's per-frame now) - in define-command, functions providing default parameter values now accept frame as parameter - in keymaps, parameter values are functions that accept frame as parameter
This commit is contained in:
parent
dea9d925a5
commit
5069e6aff1
@ -33,6 +33,5 @@
|
||||
(let [b (new-buffer name)]
|
||||
(tset buffers name b)
|
||||
b))
|
||||
:current (fn [] (let [k (next buffers)] (. buffers k)))
|
||||
:find (fn [term] (. buffers term))
|
||||
})
|
||||
|
97
command.fnl
97
command.fnl
@ -32,7 +32,7 @@
|
||||
"visit-location"
|
||||
(fn [{:url url :buffer buffer}]
|
||||
(let [b (Buffer.find buffer)] (: b :visit url)))
|
||||
[:buffer (fn [] (. (Buffer.current) :name))
|
||||
[:buffer (fn [f] f.buffer.name)
|
||||
:url #(do "http://www.example.com")
|
||||
])
|
||||
|
||||
@ -98,77 +98,74 @@
|
||||
state)
|
||||
)))
|
||||
|
||||
(fn on-input [str]
|
||||
(let [s (next-action state str)
|
||||
(fn on-input [self str]
|
||||
(let [s (next-action self.state str)
|
||||
param (if s.active (. (. s.command :params) s.this-param))]
|
||||
(set state s)
|
||||
(set self.state s)
|
||||
{
|
||||
:active s.active
|
||||
:error s.error
|
||||
:prompt (if s.active (or s.this-param "Command?" "") "")
|
||||
:default (and param (param))
|
||||
:default (and param (param self.frame))
|
||||
}))
|
||||
|
||||
(local prompt (Gtk.Label { :label ""}))
|
||||
|
||||
(local widget
|
||||
(let [w (Gtk.Entry {
|
||||
:sensitive false
|
||||
})]
|
||||
(tset w :on_activate
|
||||
(fn [event]
|
||||
(let [result (on-input event.text)]
|
||||
(set prompt.label (or result.prompt ""))
|
||||
(set w.sensitive result.active)
|
||||
(set w.text (or result.default result.error "")))))
|
||||
w))
|
||||
|
||||
(local box
|
||||
(let [box
|
||||
(Gtk.Box {
|
||||
:orientation Gtk.Orientation.HORIZONTAL
|
||||
})]
|
||||
|
||||
(box:pack_start prompt false false 15)
|
||||
(box:pack_start widget true true 5)
|
||||
box))
|
||||
|
||||
(fn update-widget-state [result]
|
||||
(fn update-widget-state [{ : entry : prompt} result]
|
||||
(set prompt.label (or result.prompt ""))
|
||||
(set widget.sensitive result.active)
|
||||
(set widget.text (or result.default result.error "")))
|
||||
(set entry.sensitive result.active)
|
||||
(set entry.text (or result.default result.error "")))
|
||||
|
||||
(fn activate []
|
||||
(fn activate [{: state : entry : prompt}]
|
||||
(tset state :active true)
|
||||
(set widget.sensitive true)
|
||||
(set widget.text "")
|
||||
(set entry.sensitive true)
|
||||
(set entry.text "")
|
||||
(set prompt.label (or state.this-param "Command" ""))
|
||||
(widget:grab_focus)
|
||||
(entry:grab_focus)
|
||||
state)
|
||||
|
||||
(fn invoke-interactively [name params]
|
||||
(fn invoke-interactively [self name params]
|
||||
(let [c (find-command name)
|
||||
supplied-params (collect [k v (pairs params)]
|
||||
(values k (v self.frame)))
|
||||
s {
|
||||
:active true
|
||||
:command c
|
||||
:collected-params params
|
||||
:collected-params supplied-params
|
||||
}]
|
||||
(set state s)
|
||||
(let [r (on-input nil)]
|
||||
(update-widget-state r)
|
||||
(widget:grab_focus)
|
||||
(set self.state s)
|
||||
(let [r (self:on-input nil)]
|
||||
(update-widget-state self r)
|
||||
(self.entry:grab_focus)
|
||||
r)))
|
||||
|
||||
(fn new-commander [frame]
|
||||
(let [entry (Gtk.Entry {:sensitive false })
|
||||
prompt (Gtk.Label { :label ""})
|
||||
box (Gtk.Box {
|
||||
:orientation Gtk.Orientation.HORIZONTAL
|
||||
})
|
||||
self {
|
||||
:state default-state
|
||||
: activate
|
||||
:active? (fn [self] self.state.active)
|
||||
: on-input
|
||||
: invoke-interactively
|
||||
: entry
|
||||
:widget box
|
||||
: prompt
|
||||
: frame
|
||||
}]
|
||||
(box:pack_start prompt false false 15)
|
||||
(box:pack_start entry true true 5)
|
||||
(tset entry :on_activate
|
||||
(fn [event]
|
||||
(let [result (self:on-input event.text)]
|
||||
(set prompt.label (or result.prompt ""))
|
||||
(set entry.sensitive result.active)
|
||||
(set entry.text (or result.default result.error "")))))
|
||||
self))
|
||||
|
||||
|
||||
{
|
||||
: activate
|
||||
:active? (fn [] state.active)
|
||||
:commander new-commander
|
||||
: define-command
|
||||
: on-input
|
||||
: invoke-interactively
|
||||
:widget box
|
||||
:_ {
|
||||
: reset-state
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
;;; when we decide how to do an init file/rc file, this will go in it
|
||||
|
||||
(local my-keymap {
|
||||
"g" ["visit-location" {:buffer "main"}]
|
||||
"g" ["visit-location" {:buffer #(. (. $1 :buffer) :name)}]
|
||||
"M-q" ["quit-browser" {}]
|
||||
"C-x" {
|
||||
"C-c" ["quit-browser" {}]
|
||||
|
16
frame.fnl
16
frame.fnl
@ -10,7 +10,9 @@
|
||||
(fn new-frame [global-keymap]
|
||||
(let [hpad 2
|
||||
vpad 2
|
||||
self {}
|
||||
recogniser (keymap.recogniser global-keymap)
|
||||
commander (Command.commander self)
|
||||
window (Gtk.Window {
|
||||
:title "Dunlin"
|
||||
:default_width 800
|
||||
@ -32,16 +34,16 @@
|
||||
|
||||
(tset window :on_key_release_event
|
||||
(fn [window event]
|
||||
(when (not (Command.active?))
|
||||
(when (not (commander:active?))
|
||||
(match (recogniser:accept-event event)
|
||||
[name params] (Command.invoke-interactively name params)
|
||||
[name params] (commander:invoke-interactively name params)
|
||||
(nil prompt) (print "prompted" prompt)))
|
||||
(when (and event.state.MOD1_MASK
|
||||
(= event.keyval (string.byte "x")))
|
||||
(Command.activate))))
|
||||
(commander:activate))))
|
||||
|
||||
(doto container
|
||||
(: :pack_start Command.widget false false vpad)
|
||||
(: :pack_start commander.widget false false vpad)
|
||||
(: :pack_start progress-bar false false vpad)
|
||||
(: :pack_start contentwidget true true vpad))
|
||||
(window:add container)
|
||||
@ -54,11 +56,13 @@
|
||||
:show-buffer (fn [self b]
|
||||
(each [_ w (pairs (contentwidget:get_children))]
|
||||
(w:hide))
|
||||
(tset self :buffer b)
|
||||
(contentwidget:pack_start b.webview true true 0)
|
||||
(b.webview:show))
|
||||
}]
|
||||
(table.insert frames f)
|
||||
f)))
|
||||
(lume.extend self f)
|
||||
(table.insert frames self)
|
||||
self)))
|
||||
|
||||
|
||||
{ :new new-frame :frames frames }
|
||||
|
@ -3,7 +3,7 @@
|
||||
(local Command (require :command))
|
||||
|
||||
(var happened false)
|
||||
(fn before [] (set happened false) (Command._.reset-state))
|
||||
(fn before [] (set happened false))
|
||||
|
||||
(Command.define-command "no-args-command" #(set happened true) [])
|
||||
|
||||
@ -13,31 +13,34 @@
|
||||
[:a #(do "3") :b #(do "2")])
|
||||
|
||||
(before)
|
||||
(let [(ok err)
|
||||
(match-try (Command.activate)
|
||||
{:active true} (Command.on-input "not-a-command")
|
||||
(let [commander (Command.commander)
|
||||
(ok err)
|
||||
(match-try (commander:activate)
|
||||
{:active true} (commander:on-input "not-a-command")
|
||||
(where {:error e :active false} (e:match "can't find command")) true
|
||||
(catch
|
||||
x (values nil (view x))))]
|
||||
(assert ok err))
|
||||
|
||||
(before)
|
||||
(let [(ok err)
|
||||
(match-try (Command.activate)
|
||||
{:active true} (Command.on-input "multiply")
|
||||
{:active true :prompt p1} (Command.on-input "2")
|
||||
{:active true :prompt p2} (Command.on-input "3")
|
||||
(let [commander (Command.commander)
|
||||
(ok err)
|
||||
(match-try (commander:activate)
|
||||
{:active true} (commander:on-input "multiply")
|
||||
{:active true :prompt p1} (commander:on-input "2")
|
||||
{:active true :prompt p2} (commander:on-input "3")
|
||||
(where {:active false} (= happened 6)) true
|
||||
(catch
|
||||
x (values nil (view x))))]
|
||||
(assert ok err))
|
||||
|
||||
(before)
|
||||
(let [(ok err)
|
||||
(let [commander (Command.commander)
|
||||
(ok err)
|
||||
(match
|
||||
(Command.invoke-interactively
|
||||
(commander:invoke-interactively
|
||||
"multiply"
|
||||
{:a "7" :b "9"})
|
||||
{:a #"7" :b #"9"})
|
||||
(where {:active false} (= happened 63)) true
|
||||
x (values nil (.. "wrong answer " (view x) " " (view happened)))
|
||||
nil (values nil "???"))]
|
||||
|
Loading…
Reference in New Issue
Block a user