diff --git a/command.fnl b/command.fnl index 5185828..80df2bd 100644 --- a/command.fnl +++ b/command.fnl @@ -20,7 +20,7 @@ (fn completion [{: widget : text : value }] (let [value (or value (assert text "must have text"))] { - :widget (or widget (Gtk.Button { :label text })) + :widget (or widget (Gtk.Label { :label text })) : text : value })) @@ -52,7 +52,7 @@ (icollect [v (_G.history:find-distinct term)] (let [label (.. v.url " " (or v.title ""))] (completion { :text v.url - :widget (Gtk.Button { : label }) + :widget (Gtk.Label { : label }) :value v.url }))) [])] @@ -147,6 +147,8 @@ (if (not result.active) (completions-widget:hide)) (set entry.text (or result.default result.error "")) + (if result.active (entry:grab_focus)) + (when widget.parent (widget.parent:set_visible_child_name (if result.active "commander" "echo-area")))) @@ -155,14 +157,29 @@ (let [parent self.completions-widget set-completions (fn [completions] - (parent:foreach #(parent:remove $1)) - (each [_ c (pairs completions)] - (parent:add - (doto c.widget - (tset :on_clicked - #(update-widget-state - self - (self:on-input-finished c.text)))))) + (let [flowbox (Gtk.FlowBox { + :activate_on_single_click true + :selection_mode Gtk.SelectionMode.SINGLE + }) + ;; I don't know why, but the flowboxchild activate signal + ;; is working only for keyboard activation not for + ;; clicking. So instead of using it we connect to + ;; child_activated, and use kids-map to find out which + ;; child it was + kids-map {}] + (parent:foreach #(parent:remove $1)) ; expect only 1 direct child + (each [_ c (pairs completions)] + (let [fbc (Gtk.FlowBoxChild)] + (tset kids-map fbc c.text) + (fbc:add c.widget) + (flowbox:add fbc))) + (tset flowbox :on_child_activated + (fn [_self child] + (match (. kids-map child) + text (update-widget-state + self + (self:on-input-finished text))))) + (parent:add flowbox)) (parent:show_all))] (match self.state {:command c :this-param param-name} @@ -210,7 +227,7 @@ prompt (Gtk.Label { :label ""}) box (Gtk.Box { :orientation Gtk.Orientation.VERTICAL }) hbox (Gtk.Box { :orientation Gtk.Orientation.HORIZONTAL }) - completions (Gtk.FlowBox) + completions (Gtk.Box { :orientation Gtk.Orientation.VERTICAL }) self { :state default-state : activate diff --git a/musing.md b/musing.md index 0dc0455..45a7d0d 100644 --- a/musing.md +++ b/musing.md @@ -66,18 +66,20 @@ focus from entry to step through the completions then RET activates * [done] back binding * [done] save url history, use it in completions * [done] autocomplete command name +* [done] keyboard navigation of completions * custom rendering for completions (e.g. buffer thumbnails) * 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 -* bind event to echo-area click, ideally dependent on what's being shown - in there +* bind event to echo-area click, ideally dependent on what's being shown in there * in general, can we bind commands to widget events? * command to create new buffer -* keyboard navigation of completions * suppress "Return is undefined" message after a command executes ---- + +can we increase the testability? e.g. for command processing, +define a command, feed in some keystrokes, diff --git a/search.fnl b/search.fnl index 5d42f9d..df2d1d6 100644 --- a/search.fnl +++ b/search.fnl @@ -35,7 +35,7 @@ (completion { :text keyword :value keyword - :widget (Gtk.Button { :label name }) + :widget (Gtk.Label { :label name }) }))))