Compare commits

..

6 Commits

Author SHA1 Message Date
4b78434ea4 extract search into a module, improve it 2023-01-17 11:30:10 +00:00
fe25203bad proof of concept search command 2023-01-17 11:03:30 +00:00
3a577b71d8 url completion allows current text as a completion option
whatever the user has typed, it should be allowable as a
URL otherwise we can only visit locations we've already been to
2023-01-17 10:45:19 +00:00
bf8fa80dac tidy, remove debug prints 2023-01-16 21:07:56 +00:00
d62b9dea3e repair command completions 2023-01-15 18:29:46 +00:00
d962dd7c41 trim outdated stuff 2023-01-15 18:23:10 +00:00
6 changed files with 80 additions and 24 deletions

View File

@ -47,14 +47,16 @@
#$1.buffer.name]
[:url
(fn [term]
(if (> (# term) 2)
(icollect [v (_G.history:find-distinct term)]
(let [label (.. v.url " " (or v.title ""))]
(completion { :text v.url
:widget (Gtk.Button { : label })
:value v.url
})))
[]))
(let [from-history
(if (> (# term) 2)
(icollect [v (_G.history:find-distinct term)]
(let [label (.. v.url " " (or v.title ""))]
(completion { :text v.url
:widget (Gtk.Button { : label })
:value v.url
})))
[])]
(lume.unique (lume.concat from-history [(completion {:text term})]))))
#($1.buffer:location)]
]
(fn [{:url url :buffer buffer}]
@ -67,6 +69,7 @@
#$1.buffer.name]]
(fn [{: buffer}] (buffer:back)))
(fn find-command [name]
(. commands name))
@ -168,8 +171,8 @@
{:command nil}
(set-completions
(collect [k _ (pairs commands)]
(if (= (k:find str 1 true) 1) (values k k)))))))
(icollect [k _ (pairs commands)]
(if (= (k:find str 1 true) 1) (completion { :text k})))))))
(fn activate [{: state : entry : prompt &as self}]
(tset state :active true)
@ -205,12 +208,8 @@
(fn new-commander [frame]
(let [entry (Gtk.Entry {:sensitive false })
prompt (Gtk.Label { :label ""})
box (Gtk.Box {
:orientation Gtk.Orientation.VERTICAL
})
hbox (Gtk.Box {
:orientation Gtk.Orientation.HORIZONTAL
})
box (Gtk.Box { :orientation Gtk.Orientation.VERTICAL })
hbox (Gtk.Box { :orientation Gtk.Orientation.HORIZONTAL })
completions (Gtk.FlowBox)
self {
:state default-state
@ -230,13 +229,9 @@
(hbox:pack_start entry true true 5)
(box:pack_start hbox true false 0)
(box:pack_start completions true true 0)
(tset entry :on_changed
(fn [event]
(self:on-input event.text)))
(tset entry :on_changed #(self:on-input $1.text))
(tset entry :on_activate
(fn [event]
(let [result (self:on-input-finished event.text)]
(update-widget-state self result))))
#(update-widget-state self (self:on-input-finished $1.text)))
self))

View File

@ -6,6 +6,8 @@
(local Frame (require :frame))
(local Buffer (require :buffer))
(local search (require :search))
;;; when we decide how to do an init file/rc file, this will go in it
(local my-keymap {

View File

@ -42,7 +42,6 @@
(s:nrows)))
(fn find-distinct [self term]
(print :self self :term term)
(let [s (self.db:prepare "select distinct v.url,pt.title from visits v left join page_titles pt on v.url = pt.url where instr(v.url, ?) >0")]
(assert (= 0 (s:bind_values term)))
(s:nrows)))

View File

@ -65,6 +65,7 @@ focus from entry to step through the completions then RET activates
* [done] display unbound key error
* [done] back binding
* [done] save url history, use it in completions
* [done] autocomplete command name
* custom rendering for completions (e.g. buffer thumbnails)
* less ugly default completions rendering
@ -74,7 +75,6 @@ focus from entry to step through the completions then RET activates
* bind event to echo-area click, ideally dependent on what's being shown
in there
* in general, can we bind commands to widget events?
* autocomplete command name
* command to create new buffer
* keyboard navigation of completions

52
search.fnl Normal file
View File

@ -0,0 +1,52 @@
(local { : Gtk } (require :lgi))
(local { : view } (require :fennel))
(local lume (require :lume))
(local {: define-command : completion } (require :command))
(local Buffer (require :buffer))
(fn url-escape [s]
(string.gsub s
"([^A-Za-z0-9_])"
#(string.format "%%%02x" (string.byte $1))))
(local searchers
{:ddg
{:name "Duck Duck Go"
:function (fn [term]
(.. "https://duckduckgo.com/?q=" (url-escape term)))
}
:google
{:name "Google"
:function (fn [term]
(.. "https://www.google.com/search?q=" (url-escape term)))
}
:luai
{:name "Lua interactive reference manual"
:function (fn [term]
(.. "https://pgl.yoyo.org/luai/i/" (url-escape term)))
}
})
(fn completions [term]
(icollect [keyword {: name : function} (pairs searchers)]
(if (string.match keyword term)
(completion {
:text keyword
:value keyword
:widget (Gtk.Button { :label name })
}))))
(define-command
"search"
[[:term
#[(completion {:text $1})]
#""]
[:buffer
#(lume.map (Buffer.match $1) #(completion { :text $1.name :value $1 }))
#$1.buffer.name]
[:engine completions #:ddg]]
(fn [{: term : engine : buffer}]
(buffer:visit ((. (. searchers engine) :function) term))))

8
test/buffer.fnl Normal file
View File

@ -0,0 +1,8 @@
(local Buffer (require :buffer))
(let [_ (Buffer.new "first")
_ (Buffer.new "second")
_ (Buffer.new "third")
_ (Buffer.new "through")
_ (Buffer.new "throughput")]
(assert (= (# (Buffer.match "")) 5)))