From f699a38bdde7c7a625bc432b0bef94cad863d32a Mon Sep 17 00:00:00 2001 From: gwern0 Date: Mon, 24 Dec 2007 05:37:35 +0100 Subject: Search.hs: mv into Actions/ per IRC suggestion darcs-hash:20071224043735-f7719-8590b54e3ee001be953ae37a0177370fbe2d6cfa.gz --- XMonad/Actions/Search.hs | 101 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 XMonad/Actions/Search.hs (limited to 'XMonad/Actions/Search.hs') diff --git a/XMonad/Actions/Search.hs b/XMonad/Actions/Search.hs new file mode 100644 index 0000000..d09c490 --- /dev/null +++ b/XMonad/Actions/Search.hs @@ -0,0 +1,101 @@ +{- | + Module : XMonad.Actions.Search + Copyright : (C) 2007 Gwern Branwen + License : None; public domain + + Maintainer : + Stability : unstable + Portability : unportable + + A module for easily running Internet searches on web sites through XMonad. + Modeled after the handy Surfraw CLI search tools + . + + Additional sites welcomed. +--------------------------------------------------------------------------- -} +module XMonad.Actions.Search ( -- * Usage + -- $usage + search, + promptSearch, + selectSearch, + + amazon, + google, + imdb, + wayback, + wikipedia, + hoogle + ) where + +import Data.Char (chr, ord, isAlpha, isMark, isDigit) +import Numeric (showIntAtBase) +import XMonad (X(), MonadIO) +import XMonad.Prompt (XPrompt(showXPrompt), mkXPrompt, XPConfig()) +import XMonad.Prompt.Shell (getShellCompl) +import XMonad.Util.Run (safeSpawn) +import XMonad.Util.XSelection (getSelection) + +-- A customized prompt. +data Search = Search +instance XPrompt Search where + showXPrompt Search = "Search: " + +-- | Escape the search string so search engines understand it. +-- Note that everything is escaped; we could be smarter and use 'isAllowedInURI' +-- but then that'd be hard enough to copy-and-paste we'd need to depend on 'network'. +escape :: String -> String +escape = escapeURIString (\c -> isAlpha c || isDigit c || isMark c) + where -- Copied from Network.URI. + escapeURIString :: + (Char -> Bool) -- a predicate which returns 'False' if should escape + -> String -- the string to process + -> String -- the resulting URI string + escapeURIString p s = concatMap (escapeURIChar p) s + escapeURIChar :: (Char->Bool) -> Char -> String + escapeURIChar p c + | p c = [c] + | otherwise = '%' : myShowHex (ord c) "" + where + myShowHex :: Int -> ShowS + myShowHex n r = case showIntAtBase 16 (toChrHex) n r of + [] -> "00" + [ch] -> ['0',ch] + cs -> cs + toChrHex d + | d < 10 = chr (ord '0' + fromIntegral d) + | otherwise = chr (ord 'A' + fromIntegral (d - 10)) + +type Browser = FilePath +type SearchEngine = String -> String + +search :: MonadIO m => Browser -> SearchEngine -> String -> m () +search browser site query = safeSpawn browser $ site query + +-- | Given a base URL, create the SearchEngine that escapes the query and +-- appends it to the base +simpleEngine :: String -> SearchEngine +simpleEngine site query = site ++ escape query + +-- The engines +amazon, google, imdb, wayback, wikipedia, hoogle :: SearchEngine +amazon = simpleEngine "http://www.amazon.com/exec/obidos/external-search?index=all&keyword=" +google = simpleEngine "http://www.google.com/search?num=100&q=" +imdb = simpleEngine "http://www.imdb.com/Find?select=all&for=" +wikipedia = simpleEngine "https://secure.wikimedia.org/wikipedia/en/wiki/Special:Search?go=Go&search=" +wayback = simpleEngine "http://web.archive.org/" +{- This doesn't seem to work, but nevertheless, it seems to be the official + method at to get the + latest backup. -} +hoogle = simpleEngine "http://www.haskell.org/hoogle/?q=" + +-- | Like 'search', but in this case, the string is not specified but grabbed +-- from the user's response to a prompt. +promptSearch :: XPConfig -> Browser -> SearchEngine -> X () +promptSearch config browser site = mkXPrompt Search config (getShellCompl []) $ search browser site + +-- | Like search, but for use with the X selection; it grabs the selection, +-- passes it to a given searchEngine and opens it in a browser. The various +-- *Selection functions specialize this to a particular search engine to make +-- things easier. +selectSearch :: MonadIO m => Browser -> SearchEngine -> m () +selectSearch browser searchEngine = search browser searchEngine =<< getSelection -- cgit v1.2.3