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