(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 match-engines [term] (icollect [keyword {: name : function} (pairs searchers)] (if (string.match keyword term) (completion { :text keyword :value keyword :widget (Gtk.Label { :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 match-engines #:ddg]] (fn [{: term : engine : buffer}] (buffer:visit ((. (. searchers engine) :function) term))))