diff --git a/frame.fnl b/frame.fnl index 260c0fb..e7eae03 100644 --- a/frame.fnl +++ b/frame.fnl @@ -12,7 +12,12 @@ vpad 2 self {} recogniser (keymap.recogniser global-keymap) + bottom-line (Gtk.Stack { + :transition_type Gtk.StackTransitionType.SLIDE_UP_DOWN + :transition_duration 100 + }) commander (Command.commander self) + echo-area (Gtk.Label { :label "echo area visible, commander hidden" }) window (Gtk.Window { :title "Dunlin" :default_width 800 @@ -39,6 +44,16 @@ n (comment (print "prop change" n value))))] + (doto bottom-line + (: :add_named echo-area "echo-area") + (: :add_named commander.widget "commander") + (: :set_visible_child_name "commander")) + + (doto container + (: :pack_start progress-bar false false vpad) + (: :pack_start contentwidget true true vpad) + (: :pack_end bottom-line false false vpad)) + (tset window :on_key_release_event (fn [window event] (when (not (commander:active?)) @@ -53,10 +68,9 @@ (= event.keyval (string.byte "x"))) (commander:activate)))) - (doto container - (: :pack_start commander.widget false false vpad) - (: :pack_start progress-bar false false vpad) - (: :pack_start contentwidget true true vpad)) + (echo-area:show) (commander.widget:show) + + (window:add container) (window:show_all) (let [f diff --git a/keymap.fnl b/keymap.fnl index 192798d..fc69554 100644 --- a/keymap.fnl +++ b/keymap.fnl @@ -86,33 +86,47 @@ (values f (compile-keymap v)) (values f v))))) +(fn ref [tbl keys] + (when tbl + (match keys + [k1 & more] (ref (. tbl k1) more) + [k1] (. tbl k1) + x tbl))) + +(let [v (ref {:a 1} [:a])] (assert (= v 1) v)) +(let [v (ref {:a {:c 7}} [:a :c])] (assert (= v 7) v)) +(let [v (ref {:a {:c 7}} [:a ])] (assert (match v {:c 7} true) (view v))) +(let [v (ref {:a {:c 7}} [:z :d])] (assert (not v) v)) + + (fn recogniser [source-keymap] (let [keymap (compile-keymap source-keymap)] - (var m keymap) + (var key-sequence []) { :accept-event (fn [_ e] (when (not (modifier? e.keyval)) (let [c (event->index e)] - (match (. m c) + (table.insert key-sequence c) + (match (ref keymap key-sequence) (where v (keymap? v)) - (do - (set m v) - (values nil (.. c " "))) + (values nil + (let [syms (lume.map key-sequence index->string)] + (table.concat syms " "))) (where v (command? v)) (do - (set m keymap) + (set key-sequence []) v) (where nil (= c "103:4")) (do - (set m keymap) + (set key-sequence []) (values nil "cancelled")) _ - (do - (set m keymap) - (values nil (.. "No binding for " (index->string c) " "))))))) + (let [syms (lume.map key-sequence index->string)] + (set key-sequence []) + (values nil (.. "No binding for " (table.concat syms " ")))))))) })) diff --git a/musing.md b/musing.md index 9355813..46b7e35 100644 --- a/musing.md +++ b/musing.md @@ -79,16 +79,26 @@ focus from entry to step through the completions then RET activates * [done] show loading progress * [done] show url when the commander is inactive * [done] visit-location url defaults to current +* [done] ESC to cancel interactive command +* [done] C-g to cancel key sequence * custom rendering for completions (e.g. buffer thumbnails) -* buffer name is often going to be useless. find buffers - by url/title +* less ugly default completions rendering +* buffer name is often going to be useless. find buffers by url/title still need some 1:1 mapping between the buffer object and a text-representable form of same * click in commander widget activates visit-location +* in general, can we bind commands to widget events? * display unbound key error -* ESC to cancel interactive command * autocomplete command name -* multiple buffers - - create buffer - - list buffers (do we need this if we have thumbnails?) +* command to create new buffer +* keyboard navigation of completions + +---- + +I think we're misusing the commander to show url and error messages +and key prompts. It's OK to have that part of the screen be multipurpose +but philosophically those things are not related to the command system. + +- hide commander when inactive and replace it with echo area +- move it to bottom?