Compare commits
6 Commits
2ceb5ad757
...
4b78434ea4
Author | SHA1 | Date | |
---|---|---|---|
4b78434ea4 | |||
fe25203bad | |||
3a577b71d8 | |||
bf8fa80dac | |||
d62b9dea3e | |||
d962dd7c41 |
39
command.fnl
39
command.fnl
@ -47,14 +47,16 @@
|
|||||||
#$1.buffer.name]
|
#$1.buffer.name]
|
||||||
[:url
|
[:url
|
||||||
(fn [term]
|
(fn [term]
|
||||||
(if (> (# term) 2)
|
(let [from-history
|
||||||
(icollect [v (_G.history:find-distinct term)]
|
(if (> (# term) 2)
|
||||||
(let [label (.. v.url " " (or v.title ""))]
|
(icollect [v (_G.history:find-distinct term)]
|
||||||
(completion { :text v.url
|
(let [label (.. v.url " " (or v.title ""))]
|
||||||
:widget (Gtk.Button { : label })
|
(completion { :text v.url
|
||||||
:value v.url
|
:widget (Gtk.Button { : label })
|
||||||
})))
|
:value v.url
|
||||||
[]))
|
})))
|
||||||
|
[])]
|
||||||
|
(lume.unique (lume.concat from-history [(completion {:text term})]))))
|
||||||
#($1.buffer:location)]
|
#($1.buffer:location)]
|
||||||
]
|
]
|
||||||
(fn [{:url url :buffer buffer}]
|
(fn [{:url url :buffer buffer}]
|
||||||
@ -67,6 +69,7 @@
|
|||||||
#$1.buffer.name]]
|
#$1.buffer.name]]
|
||||||
(fn [{: buffer}] (buffer:back)))
|
(fn [{: buffer}] (buffer:back)))
|
||||||
|
|
||||||
|
|
||||||
(fn find-command [name]
|
(fn find-command [name]
|
||||||
(. commands name))
|
(. commands name))
|
||||||
|
|
||||||
@ -168,8 +171,8 @@
|
|||||||
|
|
||||||
{:command nil}
|
{:command nil}
|
||||||
(set-completions
|
(set-completions
|
||||||
(collect [k _ (pairs commands)]
|
(icollect [k _ (pairs commands)]
|
||||||
(if (= (k:find str 1 true) 1) (values k k)))))))
|
(if (= (k:find str 1 true) 1) (completion { :text k})))))))
|
||||||
|
|
||||||
(fn activate [{: state : entry : prompt &as self}]
|
(fn activate [{: state : entry : prompt &as self}]
|
||||||
(tset state :active true)
|
(tset state :active true)
|
||||||
@ -205,12 +208,8 @@
|
|||||||
(fn new-commander [frame]
|
(fn new-commander [frame]
|
||||||
(let [entry (Gtk.Entry {:sensitive false })
|
(let [entry (Gtk.Entry {:sensitive false })
|
||||||
prompt (Gtk.Label { :label ""})
|
prompt (Gtk.Label { :label ""})
|
||||||
box (Gtk.Box {
|
box (Gtk.Box { :orientation Gtk.Orientation.VERTICAL })
|
||||||
:orientation Gtk.Orientation.VERTICAL
|
hbox (Gtk.Box { :orientation Gtk.Orientation.HORIZONTAL })
|
||||||
})
|
|
||||||
hbox (Gtk.Box {
|
|
||||||
:orientation Gtk.Orientation.HORIZONTAL
|
|
||||||
})
|
|
||||||
completions (Gtk.FlowBox)
|
completions (Gtk.FlowBox)
|
||||||
self {
|
self {
|
||||||
:state default-state
|
:state default-state
|
||||||
@ -230,13 +229,9 @@
|
|||||||
(hbox:pack_start entry true true 5)
|
(hbox:pack_start entry true true 5)
|
||||||
(box:pack_start hbox true false 0)
|
(box:pack_start hbox true false 0)
|
||||||
(box:pack_start completions true true 0)
|
(box:pack_start completions true true 0)
|
||||||
(tset entry :on_changed
|
(tset entry :on_changed #(self:on-input $1.text))
|
||||||
(fn [event]
|
|
||||||
(self:on-input event.text)))
|
|
||||||
(tset entry :on_activate
|
(tset entry :on_activate
|
||||||
(fn [event]
|
#(update-widget-state self (self:on-input-finished $1.text)))
|
||||||
(let [result (self:on-input-finished event.text)]
|
|
||||||
(update-widget-state self result))))
|
|
||||||
self))
|
self))
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
(local Frame (require :frame))
|
(local Frame (require :frame))
|
||||||
(local Buffer (require :buffer))
|
(local Buffer (require :buffer))
|
||||||
|
|
||||||
|
(local search (require :search))
|
||||||
|
|
||||||
;;; when we decide how to do an init file/rc file, this will go in it
|
;;; when we decide how to do an init file/rc file, this will go in it
|
||||||
|
|
||||||
(local my-keymap {
|
(local my-keymap {
|
||||||
|
@ -42,7 +42,6 @@
|
|||||||
(s:nrows)))
|
(s:nrows)))
|
||||||
|
|
||||||
(fn find-distinct [self term]
|
(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")]
|
(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)))
|
(assert (= 0 (s:bind_values term)))
|
||||||
(s:nrows)))
|
(s:nrows)))
|
||||||
|
@ -65,6 +65,7 @@ focus from entry to step through the completions then RET activates
|
|||||||
* [done] display unbound key error
|
* [done] display unbound key error
|
||||||
* [done] back binding
|
* [done] back binding
|
||||||
* [done] save url history, use it in completions
|
* [done] save url history, use it in completions
|
||||||
|
* [done] autocomplete command name
|
||||||
|
|
||||||
* custom rendering for completions (e.g. buffer thumbnails)
|
* custom rendering for completions (e.g. buffer thumbnails)
|
||||||
* less ugly default completions rendering
|
* 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
|
* bind event to echo-area click, ideally dependent on what's being shown
|
||||||
in there
|
in there
|
||||||
* in general, can we bind commands to widget events?
|
* in general, can we bind commands to widget events?
|
||||||
* autocomplete command name
|
|
||||||
* command to create new buffer
|
* command to create new buffer
|
||||||
* keyboard navigation of completions
|
* keyboard navigation of completions
|
||||||
|
|
||||||
|
52
search.fnl
Normal file
52
search.fnl
Normal 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
8
test/buffer.fnl
Normal 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)))
|
Loading…
Reference in New Issue
Block a user