module XMonad.Actions.Search (
search,
SearchEngine(..),
searchEngine,
searchEngineF,
promptSearch,
promptSearchBrowser,
selectSearch,
selectSearchBrowser,
isPrefixOf,
escape,
use,
intelligent,
(!>),
prefixAware,
namedEngine,
amazon,
alpha,
codesearch,
deb,
debbts,
debpts,
dictionary,
google,
hackage,
hoogle,
images,
imdb,
isohunt,
lucky,
maps,
mathworld,
openstreetmap,
scholar,
stackage,
thesaurus,
wayback,
wikipedia,
wiktionary,
youtube,
vocabulary,
duckduckgo,
multi,
Browser, Site, Query, Name, Search
) where
import Codec.Binary.UTF8.String (encode)
import Data.Char (isAlphaNum, isAscii)
import Data.List (isPrefixOf)
import Text.Printf
import XMonad (X (), liftIO)
import XMonad.Prompt (XPConfig (), XPrompt (showXPrompt, nextCompletion, commandToComplete),
getNextCompletion,
historyCompletionP, mkXPrompt)
import XMonad.Prompt.Shell (getBrowser)
import XMonad.Util.Run (safeSpawn)
import XMonad.Util.XSelection (getSelection)
data Search = Search Name
instance XPrompt Search where
showXPrompt :: Search -> String
showXPrompt (Search name :: String
name)= "Search [" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ "]: "
nextCompletion :: Search -> String -> [String] -> String
nextCompletion _ = String -> [String] -> String
getNextCompletion
commandToComplete :: Search -> String -> String
commandToComplete _ c :: String
c = String
c
escape :: String -> String
escape :: String -> String
escape = (Char -> String) -> String -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Char -> String
escapeURIChar
escapeURIChar :: Char -> String
escapeURIChar :: Char -> String
escapeURIChar c :: Char
c | Char -> Bool
isAscii Char
c Bool -> Bool -> Bool
&& Char -> Bool
isAlphaNum Char
c = [Char
c]
| Bool
otherwise = (Word8 -> String) -> [Word8] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (String -> Word8 -> String
forall r. PrintfType r => String -> r
printf "%%%02X") ([Word8] -> String) -> [Word8] -> String
forall a b. (a -> b) -> a -> b
$ String -> [Word8]
encode [Char
c]
type Browser = FilePath
type Query = String
type Site = String -> String
type Name = String
data SearchEngine = SearchEngine Name Site
use :: SearchEngine -> Site
use :: SearchEngine -> String -> String
use (SearchEngine _ engine :: String -> String
engine) = String -> String
engine
search :: Browser -> Site -> Query -> X ()
search :: String -> (String -> String) -> String -> X ()
search browser :: String
browser site :: String -> String
site query :: String
query = String -> [String] -> X ()
forall (m :: * -> *). MonadIO m => String -> [String] -> m ()
safeSpawn String
browser [String -> String
site String
query]
searchEngine :: Name -> String -> SearchEngine
searchEngine :: String -> String -> SearchEngine
searchEngine name :: String
name site :: String
site = String -> (String -> String) -> SearchEngine
searchEngineF String
name (\s :: String
s -> String
site String -> String -> String
forall a. [a] -> [a] -> [a]
++ (String -> String
escape String
s))
searchEngineF :: Name -> Site -> SearchEngine
searchEngineF :: String -> (String -> String) -> SearchEngine
searchEngineF = String -> (String -> String) -> SearchEngine
SearchEngine
amazon, alpha, codesearch, deb, debbts, debpts, dictionary, google, hackage, hoogle,
images, imdb, isohunt, lucky, maps, mathworld, openstreetmap, scholar, stackage, thesaurus, vocabulary, wayback, wikipedia, wiktionary,
youtube, duckduckgo :: SearchEngine
amazon :: SearchEngine
amazon = String -> String -> SearchEngine
searchEngine "amazon" "http://www.amazon.com/s/ref=nb_sb_noss_2?url=search-alias%3Daps&field-keywords="
alpha :: SearchEngine
alpha = String -> String -> SearchEngine
searchEngine "alpha" "http://www.wolframalpha.com/input/?i="
codesearch :: SearchEngine
codesearch = String -> String -> SearchEngine
searchEngine "codesearch" "http://www.google.com/codesearch?q="
deb :: SearchEngine
deb = String -> String -> SearchEngine
searchEngine "deb" "http://packages.debian.org/"
debbts :: SearchEngine
debbts = String -> String -> SearchEngine
searchEngine "debbts" "http://bugs.debian.org/"
debpts :: SearchEngine
debpts = String -> String -> SearchEngine
searchEngine "debpts" "http://packages.qa.debian.org/"
dictionary :: SearchEngine
dictionary = String -> String -> SearchEngine
searchEngine "dict" "http://dictionary.reference.com/browse/"
google :: SearchEngine
google = String -> String -> SearchEngine
searchEngine "google" "http://www.google.com/search?num=100&q="
hackage :: SearchEngine
hackage = String -> String -> SearchEngine
searchEngine "hackage" "http://hackage.haskell.org/package/"
hoogle :: SearchEngine
hoogle = String -> String -> SearchEngine
searchEngine "hoogle" "http://www.haskell.org/hoogle/?q="
images :: SearchEngine
images = String -> String -> SearchEngine
searchEngine "images" "http://images.google.fr/images?q="
imdb :: SearchEngine
imdb = String -> String -> SearchEngine
searchEngine "imdb" "http://www.imdb.com/find?s=all&q="
isohunt :: SearchEngine
isohunt = String -> String -> SearchEngine
searchEngine "isohunt" "http://isohunt.com/torrents/?ihq="
lucky :: SearchEngine
lucky = String -> String -> SearchEngine
searchEngine "lucky" "http://www.google.com/search?btnI&q="
maps :: SearchEngine
maps = String -> String -> SearchEngine
searchEngine "maps" "http://maps.google.com/maps?q="
mathworld :: SearchEngine
mathworld = String -> String -> SearchEngine
searchEngine "mathworld" "http://mathworld.wolfram.com/search/?query="
openstreetmap :: SearchEngine
openstreetmap = String -> String -> SearchEngine
searchEngine "openstreetmap" "http://gazetteer.openstreetmap.org/namefinder/?find="
scholar :: SearchEngine
scholar = String -> String -> SearchEngine
searchEngine "scholar" "http://scholar.google.com/scholar?q="
stackage :: SearchEngine
stackage = String -> String -> SearchEngine
searchEngine "stackage" "www.stackage.org/lts/hoogle?q="
thesaurus :: SearchEngine
thesaurus = String -> String -> SearchEngine
searchEngine "thesaurus" "http://thesaurus.reference.com/search?q="
wikipedia :: SearchEngine
wikipedia = String -> String -> SearchEngine
searchEngine "wiki" "http://en.wikipedia.org/wiki/Special:Search?go=Go&search="
wiktionary :: SearchEngine
wiktionary = String -> String -> SearchEngine
searchEngine "wikt" "http://en.wiktionary.org/wiki/Special:Search?go=Go&search="
youtube :: SearchEngine
youtube = String -> String -> SearchEngine
searchEngine "youtube" "http://www.youtube.com/results?search_type=search_videos&search_query="
wayback :: SearchEngine
wayback = String -> (String -> String) -> SearchEngine
searchEngineF "wayback" ("http://web.archive.org/web/*/"String -> String -> String
forall a. [a] -> [a] -> [a]
++)
vocabulary :: SearchEngine
vocabulary = String -> String -> SearchEngine
searchEngine "vocabulary" "http://www.vocabulary.com/search?q="
duckduckgo :: SearchEngine
duckduckgo = String -> String -> SearchEngine
searchEngine "duckduckgo" "https://duckduckgo.com/?t=lm&q="
multi :: SearchEngine
multi :: SearchEngine
multi = String -> SearchEngine -> SearchEngine
namedEngine "multi" (SearchEngine -> SearchEngine) -> SearchEngine -> SearchEngine
forall a b. (a -> b) -> a -> b
$ (SearchEngine -> SearchEngine -> SearchEngine)
-> [SearchEngine] -> SearchEngine
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 SearchEngine -> SearchEngine -> SearchEngine
(!>) [SearchEngine
amazon, SearchEngine
alpha, SearchEngine
codesearch, SearchEngine
deb, SearchEngine
debbts, SearchEngine
debpts, SearchEngine
dictionary, SearchEngine
google, SearchEngine
hackage, SearchEngine
hoogle, SearchEngine
images, SearchEngine
imdb, SearchEngine
isohunt, SearchEngine
lucky, SearchEngine
maps, SearchEngine
mathworld, SearchEngine
openstreetmap, SearchEngine
scholar, SearchEngine
thesaurus, SearchEngine
wayback, SearchEngine
wikipedia, SearchEngine
wiktionary, SearchEngine
duckduckgo, (SearchEngine -> SearchEngine
prefixAware SearchEngine
google)]
intelligent :: SearchEngine -> SearchEngine
intelligent :: SearchEngine -> SearchEngine
intelligent (SearchEngine name :: String
name site :: String -> String
site) = String -> (String -> String) -> SearchEngine
searchEngineF String
name (\s :: String
s -> if ((String, String) -> String
forall a b. (a, b) -> a
fst ((String, String) -> String) -> (String, String) -> String
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==':') String
s) String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ["http", "https", "ftp"] then String
s else (String -> String
site String
s))
removeColonPrefix :: String -> String
removeColonPrefix :: String -> String
removeColonPrefix s :: String
s = if ':' Char -> String -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
s then Int -> String -> String
forall a. Int -> [a] -> [a]
drop 1 (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (':' Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/=) String
s else String
s
(!>) :: SearchEngine -> SearchEngine -> SearchEngine
(SearchEngine name1 :: String
name1 site1 :: String -> String
site1) !> :: SearchEngine -> SearchEngine -> SearchEngine
!> (SearchEngine name2 :: String
name2 site2 :: String -> String
site2) = String -> (String -> String) -> SearchEngine
searchEngineF (String
name1 String -> String -> String
forall a. [a] -> [a] -> [a]
++ "/" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
name2) (\s :: String
s -> if (String
name1String -> String -> String
forall a. [a] -> [a] -> [a]
++":") String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
s then String -> String
site1 (String -> String
removeColonPrefix String
s) else String -> String
site2 String
s)
prefixAware :: SearchEngine -> SearchEngine
prefixAware :: SearchEngine -> SearchEngine
prefixAware (SearchEngine name :: String
name site :: String -> String
site) = String -> (String -> String) -> SearchEngine
SearchEngine String
name (\s :: String
s -> if (String
nameString -> String -> String
forall a. [a] -> [a] -> [a]
++":") String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
s then String -> String
site (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String -> String
removeColonPrefix String
s else String -> String
site String
s)
namedEngine :: Name -> SearchEngine -> SearchEngine
namedEngine :: String -> SearchEngine -> SearchEngine
namedEngine name :: String
name (SearchEngine _ site :: String -> String
site) = String -> (String -> String) -> SearchEngine
searchEngineF String
name String -> String
site
promptSearchBrowser :: XPConfig -> Browser -> SearchEngine -> X ()
promptSearchBrowser :: XPConfig -> String -> SearchEngine -> X ()
promptSearchBrowser config :: XPConfig
config browser :: String
browser (SearchEngine name :: String
name site :: String -> String
site) =
Search -> XPConfig -> ComplFunction -> (String -> X ()) -> X ()
forall p.
XPrompt p =>
p -> XPConfig -> ComplFunction -> (String -> X ()) -> X ()
mkXPrompt (String -> Search
Search String
name) XPConfig
config ((String -> Bool) -> ComplFunction
historyCompletionP ("Search [" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf`)) ((String -> X ()) -> X ()) -> (String -> X ()) -> X ()
forall a b. (a -> b) -> a -> b
$ String -> (String -> String) -> String -> X ()
search String
browser String -> String
site
promptSearch :: XPConfig -> SearchEngine -> X ()
promptSearch :: XPConfig -> SearchEngine -> X ()
promptSearch config :: XPConfig
config engine :: SearchEngine
engine = IO String -> X String
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO String
getBrowser X String -> (String -> X ()) -> X ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ browser :: String
browser -> XPConfig -> String -> SearchEngine -> X ()
promptSearchBrowser XPConfig
config String
browser SearchEngine
engine
selectSearchBrowser :: Browser -> SearchEngine -> X ()
selectSearchBrowser :: String -> SearchEngine -> X ()
selectSearchBrowser browser :: String
browser (SearchEngine _ site :: String -> String
site) = String -> (String -> String) -> String -> X ()
search String
browser String -> String
site (String -> X ()) -> X String -> X ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< X String
forall (m :: * -> *). MonadIO m => m String
getSelection
selectSearch :: SearchEngine -> X ()
selectSearch :: SearchEngine -> X ()
selectSearch engine :: SearchEngine
engine = IO String -> X String
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO String
getBrowser X String -> (String -> X ()) -> X ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \browser :: String
browser -> String -> SearchEngine -> X ()
selectSearchBrowser String
browser SearchEngine
engine