{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeApplications #-}
module BM
(
version
, Argument
, Command
, Error
, Keyword
, ParameterName
, ParameterValue
, Trace
, Url
, Config(..)
, Bookmark(..)
, Query(..)
, Parameter(..)
, Proc(..)
, run
, getCompletion
) where
import qualified Data.Aeson as A
import Data.Aeson (FromJSON, (.:), (.:?), (.!=))
import qualified Data.Aeson.Types as AT
import Data.List (intercalate, isPrefixOf)
import Data.Maybe (fromMaybe)
import Data.Version (showVersion)
import qualified System.Info
import qualified Data.DList as DList
import Data.DList (DList)
import qualified Network.URI as URI
import qualified Data.Scientific as Sci
import qualified Data.Text as T
import Control.Monad.Trans.Writer (Writer, runWriter, tell)
import qualified Data.Vector as V
import Data.Vector (Vector)
import qualified Paths_bm as Project
version :: String
version :: String
version = String
"bm-haskell " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Version -> String
showVersion Version
Project.version
defaultCommand :: Command
defaultCommand :: String
defaultCommand = case String
System.Info.os of
String
"mingw32" -> String
"start"
String
"darwin" -> String
"open"
String
_other -> String
"xdg-open"
defaultParameter :: ParameterName
defaultParameter :: String
defaultParameter = String
"q"
type Argument = String
type Command = FilePath
type Error = String
type Keyword = String
type ParameterName = String
type ParameterValue = String
type Trace = String
type Url = String
data Config
= Config
{ Config -> String
configCommand :: !Command
, Config -> Vector Bookmark
configArgs :: !(Vector Bookmark)
}
deriving Int -> Config -> String -> String
[Config] -> String -> String
Config -> String
(Int -> Config -> String -> String)
-> (Config -> String)
-> ([Config] -> String -> String)
-> Show Config
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [Config] -> String -> String
$cshowList :: [Config] -> String -> String
show :: Config -> String
$cshow :: Config -> String
showsPrec :: Int -> Config -> String -> String
$cshowsPrec :: Int -> Config -> String -> String
Show
instance FromJSON Config where
parseJSON :: Value -> Parser Config
parseJSON = String -> (Object -> Parser Config) -> Value -> Parser Config
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject String
"Config" ((Object -> Parser Config) -> Value -> Parser Config)
-> (Object -> Parser Config) -> Value -> Parser Config
forall a b. (a -> b) -> a -> b
$ \Object
o ->
String -> Vector Bookmark -> Config
Config
(String -> Vector Bookmark -> Config)
-> Parser String -> Parser (Vector Bookmark -> Config)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser (Maybe String)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"command" Parser (Maybe String) -> String -> Parser String
forall a. Parser (Maybe a) -> a -> Parser a
.!= String
defaultCommand
Parser (Vector Bookmark -> Config)
-> Parser (Vector Bookmark) -> Parser Config
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser (Vector Bookmark)
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"args"
data Bookmark
= Bookmark
{ Bookmark -> String
keyword :: !Keyword
, Bookmark -> Maybe String
mCommand :: !(Maybe Command)
, Bookmark -> Maybe String
mUrl :: !(Maybe Url)
, Bookmark -> Either Query (Vector Bookmark)
queryOrArgs :: !(Either Query (Vector Bookmark))
}
deriving Int -> Bookmark -> String -> String
[Bookmark] -> String -> String
Bookmark -> String
(Int -> Bookmark -> String -> String)
-> (Bookmark -> String)
-> ([Bookmark] -> String -> String)
-> Show Bookmark
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [Bookmark] -> String -> String
$cshowList :: [Bookmark] -> String -> String
show :: Bookmark -> String
$cshow :: Bookmark -> String
showsPrec :: Int -> Bookmark -> String -> String
$cshowsPrec :: Int -> Bookmark -> String -> String
Show
instance FromJSON Bookmark where
parseJSON :: Value -> Parser Bookmark
parseJSON = String -> (Object -> Parser Bookmark) -> Value -> Parser Bookmark
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject String
"Bookmark" ((Object -> Parser Bookmark) -> Value -> Parser Bookmark)
-> (Object -> Parser Bookmark) -> Value -> Parser Bookmark
forall a b. (a -> b) -> a -> b
$ \Object
o -> do
String
keyword <- Value -> Parser String
parseToString (Value -> Parser String) -> Parser Value -> Parser String
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Object
o Object -> Key -> Parser Value
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"keyword"
Maybe String
mCommand <- Object
o Object -> Key -> Parser (Maybe String)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"command"
Maybe String
mUrl <- Object
o Object -> Key -> Parser (Maybe String)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"url"
Maybe Query
mQuery <- Object
o Object -> Key -> Parser (Maybe Query)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"query"
Maybe (Vector Bookmark)
mArgs <- Object
o Object -> Key -> Parser (Maybe (Vector Bookmark))
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"args"
Either Query (Vector Bookmark)
queryOrArgs <- case (Maybe Query
mQuery, Maybe (Vector Bookmark)
mArgs) of
(Maybe Query
Nothing, Just Vector Bookmark
args) -> Either Query (Vector Bookmark)
-> Parser (Either Query (Vector Bookmark))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either Query (Vector Bookmark)
-> Parser (Either Query (Vector Bookmark)))
-> Either Query (Vector Bookmark)
-> Parser (Either Query (Vector Bookmark))
forall a b. (a -> b) -> a -> b
$ Vector Bookmark -> Either Query (Vector Bookmark)
forall a b. b -> Either a b
Right Vector Bookmark
args
(Just Query
query, Maybe (Vector Bookmark)
Nothing) -> Either Query (Vector Bookmark)
-> Parser (Either Query (Vector Bookmark))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either Query (Vector Bookmark)
-> Parser (Either Query (Vector Bookmark)))
-> Either Query (Vector Bookmark)
-> Parser (Either Query (Vector Bookmark))
forall a b. (a -> b) -> a -> b
$ Query -> Either Query (Vector Bookmark)
forall a b. a -> Either a b
Left Query
query
(Maybe Query
Nothing, Maybe (Vector Bookmark)
Nothing) -> Either Query (Vector Bookmark)
-> Parser (Either Query (Vector Bookmark))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either Query (Vector Bookmark)
-> Parser (Either Query (Vector Bookmark)))
-> Either Query (Vector Bookmark)
-> Parser (Either Query (Vector Bookmark))
forall a b. (a -> b) -> a -> b
$ Vector Bookmark -> Either Query (Vector Bookmark)
forall a b. b -> Either a b
Right Vector Bookmark
forall a. Vector a
V.empty
(Just{}, Just{}) -> String -> Parser (Either Query (Vector Bookmark))
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser (Either Query (Vector Bookmark)))
-> String -> Parser (Either Query (Vector Bookmark))
forall a b. (a -> b) -> a -> b
$
String
"bookmark has both query and args: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
keyword
Bookmark -> Parser Bookmark
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bookmark :: String
-> Maybe String
-> Maybe String
-> Either Query (Vector Bookmark)
-> Bookmark
Bookmark{String
Maybe String
Either Query (Vector Bookmark)
queryOrArgs :: Either Query (Vector Bookmark)
mUrl :: Maybe String
mCommand :: Maybe String
keyword :: String
queryOrArgs :: Either Query (Vector Bookmark)
mUrl :: Maybe String
mCommand :: Maybe String
keyword :: String
..}
data Query
= Query
{ Query -> String
action :: !Url
, Query -> String
parameter :: !ParameterName
, Query -> Vector Parameter
hiddenParameters :: !(Vector Parameter)
}
deriving Int -> Query -> String -> String
[Query] -> String -> String
Query -> String
(Int -> Query -> String -> String)
-> (Query -> String) -> ([Query] -> String -> String) -> Show Query
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [Query] -> String -> String
$cshowList :: [Query] -> String -> String
show :: Query -> String
$cshow :: Query -> String
showsPrec :: Int -> Query -> String -> String
$cshowsPrec :: Int -> Query -> String -> String
Show
instance FromJSON Query where
parseJSON :: Value -> Parser Query
parseJSON = String -> (Object -> Parser Query) -> Value -> Parser Query
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject String
"Query" ((Object -> Parser Query) -> Value -> Parser Query)
-> (Object -> Parser Query) -> Value -> Parser Query
forall a b. (a -> b) -> a -> b
$ \Object
o ->
String -> String -> Vector Parameter -> Query
Query
(String -> String -> Vector Parameter -> Query)
-> Parser String -> Parser (String -> Vector Parameter -> Query)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser String
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"action"
Parser (String -> Vector Parameter -> Query)
-> Parser String -> Parser (Vector Parameter -> Query)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser (Maybe String)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"parameter" Parser (Maybe String) -> String -> Parser String
forall a. Parser (Maybe a) -> a -> Parser a
.!= String
defaultParameter
Parser (Vector Parameter -> Query)
-> Parser (Vector Parameter) -> Parser Query
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser (Maybe (Vector Parameter))
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"hidden" Parser (Maybe (Vector Parameter))
-> Vector Parameter -> Parser (Vector Parameter)
forall a. Parser (Maybe a) -> a -> Parser a
.!= Vector Parameter
forall a. Vector a
V.empty
data Parameter
= Parameter
{ Parameter -> String
name :: !ParameterName
, Parameter -> String
value :: !ParameterValue
}
deriving Int -> Parameter -> String -> String
[Parameter] -> String -> String
Parameter -> String
(Int -> Parameter -> String -> String)
-> (Parameter -> String)
-> ([Parameter] -> String -> String)
-> Show Parameter
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [Parameter] -> String -> String
$cshowList :: [Parameter] -> String -> String
show :: Parameter -> String
$cshow :: Parameter -> String
showsPrec :: Int -> Parameter -> String -> String
$cshowsPrec :: Int -> Parameter -> String -> String
Show
instance FromJSON Parameter where
parseJSON :: Value -> Parser Parameter
parseJSON = String -> (Object -> Parser Parameter) -> Value -> Parser Parameter
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject String
"Parameter" ((Object -> Parser Parameter) -> Value -> Parser Parameter)
-> (Object -> Parser Parameter) -> Value -> Parser Parameter
forall a b. (a -> b) -> a -> b
$ \Object
o ->
String -> String -> Parameter
Parameter
(String -> String -> Parameter)
-> Parser String -> Parser (String -> Parameter)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser String
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"name"
Parser (String -> Parameter) -> Parser String -> Parser Parameter
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Value -> Parser String
parseToString (Value -> Parser String) -> Parser Value -> Parser String
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Object
o Object -> Key -> Parser Value
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"value")
encodeParameter :: Parameter -> String
encodeParameter :: Parameter -> String
encodeParameter Parameter{String
value :: String
name :: String
value :: Parameter -> String
name :: Parameter -> String
..} = String -> String
encodePart String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
encodePart String
value
where
encodePart :: String -> String
encodePart :: String -> String
encodePart
= (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map (\Char
c -> if Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ' then Char
'+' else Char
c)
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> String -> String
URI.escapeURIString (Bool -> Bool -> Bool
(||) (Bool -> Bool -> Bool) -> (Char -> Bool) -> Char -> Bool -> Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Char -> Bool
URI.isUnreserved (Char -> Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' '))
data Proc
= Proc
{ Proc -> String
command :: !Command
, Proc -> [String]
arguments :: ![Argument]
}
deriving (Proc -> Proc -> Bool
(Proc -> Proc -> Bool) -> (Proc -> Proc -> Bool) -> Eq Proc
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Proc -> Proc -> Bool
$c/= :: Proc -> Proc -> Bool
== :: Proc -> Proc -> Bool
$c== :: Proc -> Proc -> Bool
Eq, Int -> Proc -> String -> String
[Proc] -> String -> String
Proc -> String
(Int -> Proc -> String -> String)
-> (Proc -> String) -> ([Proc] -> String -> String) -> Show Proc
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [Proc] -> String -> String
$cshowList :: [Proc] -> String -> String
show :: Proc -> String
$cshow :: Proc -> String
showsPrec :: Int -> Proc -> String -> String
$cshowsPrec :: Int -> Proc -> String -> String
Show)
run
:: Config
-> [Argument]
-> (Either Error Proc, [Trace])
run :: Config -> [String] -> (Either String Proc, [String])
run Config{String
Vector Bookmark
configArgs :: Vector Bookmark
configCommand :: String
configArgs :: Config -> Vector Bookmark
configCommand :: Config -> String
..} [String]
cliArgs = (DList String -> [String])
-> (Either String Proc, DList String)
-> (Either String Proc, [String])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap DList String -> [String]
forall a. DList a -> [a]
DList.toList ((Either String Proc, DList String)
-> (Either String Proc, [String]))
-> (Writer (DList String) (Either String Proc)
-> (Either String Proc, DList String))
-> Writer (DList String) (Either String Proc)
-> (Either String Proc, [String])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Writer (DList String) (Either String Proc)
-> (Either String Proc, DList String)
forall w a. Writer w a -> (a, w)
runWriter (Writer (DList String) (Either String Proc)
-> (Either String Proc, [String]))
-> Writer (DList String) (Either String Proc)
-> (Either String Proc, [String])
forall a b. (a -> b) -> a -> b
$ do
String -> Writer (DList String) ()
trace (String -> Writer (DList String) ())
-> String -> Writer (DList String) ()
forall a b. (a -> b) -> a -> b
$ String -> String
formatCommand String
configCommand
String
-> Vector Bookmark
-> [String]
-> Writer (DList String) (Either String Proc)
loop String
configCommand Vector Bookmark
configArgs [String]
cliArgs
where
loop
:: Command
-> Vector Bookmark
-> [Argument]
-> Writer (DList Trace) (Either Error Proc)
loop :: String
-> Vector Bookmark
-> [String]
-> Writer (DList String) (Either String Proc)
loop String
cmd Vector Bookmark
bms (String
arg:[String]
args) = case (Bookmark -> Bool) -> Vector Bookmark -> Maybe Bookmark
forall a. (a -> Bool) -> Vector a -> Maybe a
V.find (String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
isPrefixOf String
arg (String -> Bool) -> (Bookmark -> String) -> Bookmark -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bookmark -> String
keyword) Vector Bookmark
bms of
Just Bookmark
bm -> do
String -> Writer (DList String) ()
trace (String -> Writer (DList String) ())
-> String -> Writer (DList String) ()
forall a b. (a -> b) -> a -> b
$ Bookmark -> String
formatBookmark Bookmark
bm
case Bookmark -> Either Query (Vector Bookmark)
queryOrArgs Bookmark
bm of
Left Query
query
| [String] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
args -> case Bookmark -> Maybe String
mUrl Bookmark
bm of
Just String
url -> String -> String -> Writer (DList String) (Either String Proc)
openUrl (String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe String
cmd (Maybe String -> String) -> Maybe String -> String
forall a b. (a -> b) -> a -> b
$ Bookmark -> Maybe String
mCommand Bookmark
bm) String
url
Maybe String
Nothing -> String -> Writer (DList String) (Either String Proc)
returnError (String -> Writer (DList String) (Either String Proc))
-> String -> Writer (DList String) (Either String Proc)
forall a b. (a -> b) -> a -> b
$ String
"no query for " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Bookmark -> String
keyword Bookmark
bm
| Bool
otherwise -> String
-> Query -> [String] -> Writer (DList String) (Either String Proc)
openQuery (String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe String
cmd (Maybe String -> String) -> Maybe String -> String
forall a b. (a -> b) -> a -> b
$ Bookmark -> Maybe String
mCommand Bookmark
bm) Query
query [String]
args
Right Vector Bookmark
bms'
| [String] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
args -> case Bookmark -> Maybe String
mUrl Bookmark
bm of
Just String
url -> String -> String -> Writer (DList String) (Either String Proc)
openUrl (String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe String
cmd (Maybe String -> String) -> Maybe String -> String
forall a b. (a -> b) -> a -> b
$ Bookmark -> Maybe String
mCommand Bookmark
bm) String
url
Maybe String
Nothing -> case Vector Bookmark
bms' Vector Bookmark -> Int -> Maybe Bookmark
forall a. Vector a -> Int -> Maybe a
V.!? Int
0 of
Just Bookmark
bm' ->
String
-> Vector Bookmark
-> [String]
-> Writer (DList String) (Either String Proc)
loop (String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe String
cmd (Maybe String -> String) -> Maybe String -> String
forall a b. (a -> b) -> a -> b
$ Bookmark -> Maybe String
mCommand Bookmark
bm) Vector Bookmark
bms' [Bookmark -> String
keyword Bookmark
bm']
Maybe Bookmark
Nothing -> String -> Writer (DList String) (Either String Proc)
returnError (String -> Writer (DList String) (Either String Proc))
-> String -> Writer (DList String) (Either String Proc)
forall a b. (a -> b) -> a -> b
$ String
"no URL for " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Bookmark -> String
keyword Bookmark
bm
| Bool
otherwise -> String
-> Vector Bookmark
-> [String]
-> Writer (DList String) (Either String Proc)
loop (String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe String
cmd (Maybe String -> String) -> Maybe String -> String
forall a b. (a -> b) -> a -> b
$ Bookmark -> Maybe String
mCommand Bookmark
bm) Vector Bookmark
bms' [String]
args
Maybe Bookmark
Nothing -> String -> Writer (DList String) (Either String Proc)
returnError (String -> Writer (DList String) (Either String Proc))
-> String -> Writer (DList String) (Either String Proc)
forall a b. (a -> b) -> a -> b
$ String
"unknown argument: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
arg
loop String
_cmd Vector Bookmark
_bms [] = String -> Writer (DList String) (Either String Proc)
returnError String
"no arguments"
returnError :: Error -> Writer (DList Trace) (Either Error Proc)
returnError :: String -> Writer (DList String) (Either String Proc)
returnError = Either String Proc -> Writer (DList String) (Either String Proc)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String Proc -> Writer (DList String) (Either String Proc))
-> (String -> Either String Proc)
-> String
-> Writer (DList String) (Either String Proc)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Either String Proc
forall a b. a -> Either a b
Left
openUrl :: Command -> Url -> Writer (DList Trace) (Either Error Proc)
openUrl :: String -> String -> Writer (DList String) (Either String Proc)
openUrl String
cmd String
url = do
String -> Writer (DList String) ()
trace (String -> Writer (DList String) ())
-> String -> Writer (DList String) ()
forall a b. (a -> b) -> a -> b
$ [String] -> String
unwords [String
cmd, String
url]
Either String Proc -> Writer (DList String) (Either String Proc)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String Proc -> Writer (DList String) (Either String Proc))
-> (Proc -> Either String Proc)
-> Proc
-> Writer (DList String) (Either String Proc)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proc -> Either String Proc
forall a b. b -> Either a b
Right (Proc -> Writer (DList String) (Either String Proc))
-> Proc -> Writer (DList String) (Either String Proc)
forall a b. (a -> b) -> a -> b
$ String -> [String] -> Proc
Proc String
cmd [String
url]
openQuery
:: Command
-> Query
-> [Argument]
-> Writer (DList Trace) (Either Error Proc)
openQuery :: String
-> Query -> [String] -> Writer (DList String) (Either String Proc)
openQuery String
cmd Query{String
Vector Parameter
hiddenParameters :: Vector Parameter
parameter :: String
action :: String
hiddenParameters :: Query -> Vector Parameter
parameter :: Query -> String
action :: Query -> String
..} [String]
args
= String -> String -> Writer (DList String) (Either String Proc)
openUrl String
cmd
(String -> Writer (DList String) (Either String Proc))
-> ([Parameter] -> String)
-> [Parameter]
-> Writer (DList String) (Either String Proc)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String
action String -> String -> String
forall a. [a] -> [a] -> [a]
++)
(String -> String)
-> ([Parameter] -> String) -> [Parameter] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char
'?' Char -> String -> String
forall a. a -> [a] -> [a]
:)
(String -> String)
-> ([Parameter] -> String) -> [Parameter] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"&"
([String] -> String)
-> ([Parameter] -> [String]) -> [Parameter] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Parameter -> String) -> [Parameter] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Parameter -> String
encodeParameter
([Parameter] -> Writer (DList String) (Either String Proc))
-> [Parameter] -> Writer (DList String) (Either String Proc)
forall a b. (a -> b) -> a -> b
$ String -> String -> Parameter
Parameter String
parameter ([String] -> String
unwords [String]
args) Parameter -> [Parameter] -> [Parameter]
forall a. a -> [a] -> [a]
: Vector Parameter -> [Parameter]
forall a. Vector a -> [a]
V.toList Vector Parameter
hiddenParameters
trace :: Trace -> Writer (DList Trace) ()
trace :: String -> Writer (DList String) ()
trace = DList String -> Writer (DList String) ()
forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
tell (DList String -> Writer (DList String) ())
-> (String -> DList String) -> String -> Writer (DList String) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> DList String
forall a. a -> DList a
DList.singleton
formatCommand :: Command -> Trace
formatCommand :: String -> String
formatCommand = (Char
'[' Char -> String -> String
forall a. a -> [a] -> [a]
:) (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"]")
formatKeyword :: Keyword -> Trace
formatKeyword :: String -> String
formatKeyword = (Char
'<' Char -> String -> String
forall a. a -> [a] -> [a]
:) (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
">")
formatBookmark :: Bookmark -> Trace
formatBookmark :: Bookmark -> String
formatBookmark Bookmark{String
Maybe String
Either Query (Vector Bookmark)
queryOrArgs :: Either Query (Vector Bookmark)
mUrl :: Maybe String
mCommand :: Maybe String
keyword :: String
queryOrArgs :: Bookmark -> Either Query (Vector Bookmark)
mUrl :: Bookmark -> Maybe String
mCommand :: Bookmark -> Maybe String
keyword :: Bookmark -> String
..} = case Maybe String
mCommand of
Just String
command -> [String] -> String
unwords [String -> String
formatKeyword String
keyword, String -> String
formatCommand String
command]
Maybe String
Nothing -> String -> String
formatKeyword String
keyword
getCompletion
:: Config
-> [Argument]
-> [Argument]
getCompletion :: Config -> [String] -> [String]
getCompletion Config{String
Vector Bookmark
configArgs :: Vector Bookmark
configCommand :: String
configArgs :: Config -> Vector Bookmark
configCommand :: Config -> String
..} = Vector Bookmark -> [String] -> [String]
loop Vector Bookmark
configArgs
where
loop :: Vector Bookmark -> [Argument] -> [Argument]
loop :: Vector Bookmark -> [String] -> [String]
loop Vector Bookmark
bms [String
arg] = (String -> Bool) -> [String] -> [String]
forall a. (a -> Bool) -> [a] -> [a]
filter (String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
isPrefixOf String
arg) ([String] -> [String])
-> ([Bookmark] -> [String]) -> [Bookmark] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bookmark -> String) -> [Bookmark] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Bookmark -> String
keyword ([Bookmark] -> [String]) -> [Bookmark] -> [String]
forall a b. (a -> b) -> a -> b
$ Vector Bookmark -> [Bookmark]
forall a. Vector a -> [a]
V.toList Vector Bookmark
bms
loop Vector Bookmark
bms (String
arg:[String]
args) = case (Bookmark -> Bool) -> Vector Bookmark -> Maybe Bookmark
forall a. (a -> Bool) -> Vector a -> Maybe a
V.find (String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
isPrefixOf String
arg (String -> Bool) -> (Bookmark -> String) -> Bookmark -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bookmark -> String
keyword) Vector Bookmark
bms of
Just Bookmark
bm -> case Bookmark -> Either Query (Vector Bookmark)
queryOrArgs Bookmark
bm of
Left{} -> []
Right Vector Bookmark
bms' -> Vector Bookmark -> [String] -> [String]
loop Vector Bookmark
bms' [String]
args
Maybe Bookmark
Nothing -> []
loop Vector Bookmark
_bms [] = []
parseToString :: A.Value -> AT.Parser String
parseToString :: Value -> Parser String
parseToString = \case
(A.String Text
t) -> String -> Parser String
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> Parser String) -> String -> Parser String
forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack Text
t
(A.Number Scientific
n) -> String -> Parser String
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> Parser String)
-> (Either Double Integer -> String)
-> Either Double Integer
-> Parser String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Double -> String)
-> (Integer -> String) -> Either Double Integer -> String
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Show Double => Double -> String
forall a. Show a => a -> String
show @Double) (Show Integer => Integer -> String
forall a. Show a => a -> String
show @Integer) (Either Double Integer -> Parser String)
-> Either Double Integer -> Parser String
forall a b. (a -> b) -> a -> b
$
Scientific -> Either Double Integer
forall r i. (RealFloat r, Integral i) => Scientific -> Either r i
Sci.floatingOrInteger Scientific
n
(A.Bool Bool
b) -> String -> Parser String
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> Parser String) -> String -> Parser String
forall a b. (a -> b) -> a -> b
$ if Bool
b then String
"true" else String
"false"
Value
A.Null -> String -> Parser String
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"null"
A.Array{} -> String -> Parser String
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"unexpected array"
A.Object{} -> String -> Parser String
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"unexpected object"