Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions iris.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ common common-options

default-language: Haskell2010
default-extensions: ConstraintKinds
DeriveAnyClass
DeriveGeneric
DerivingStrategies
GeneralizedNewtypeDeriving
Expand All @@ -67,16 +68,22 @@ library
exposed-modules:
Iris
Iris.App
Iris.Browse
Iris.Cli
Iris.Cli.Browse
Iris.Cli.Version
Iris.Colour
Iris.Colour.Formatting
Iris.Colour.Mode
Iris.Env

build-depends:
, ansi-terminal ^>= 0.11
, directory ^>= 1.3
, bytestring >= 0.10 && < 0.12
, mtl >= 2.2 && < 2.4
, optparse-applicative ^>= 0.17
, process ^>= 1.6

executable iris-example
import: common-options
Expand Down
4 changes: 4 additions & 0 deletions src/Iris.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ Haskell CLI framework

module Iris
( module Iris.App
, module Iris.Browse
, module Iris.Cli
, module Iris.Colour
, module Iris.Env
) where

import Iris.App
import Iris.Browse
import Iris.Cli
import Iris.Colour
import Iris.Env
149 changes: 149 additions & 0 deletions src/Iris/Browse.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
{- |
Module : Iris.Browse
Copyright : (c) 2020 Kowainik
(c) 2022 Dmitrii Kovanikov
SPDX-License-Identifier : MPL-2.0
Maintainer : Dmitrii Kovanikov <[email protected]>
Stability : Experimental
Portability : Portable

Implements a function that opens a given file in a browser.

@since 0.0.0.0
-}

module Iris.Browse
( openInBrowser
, BrowseException (..)
) where

import Control.Exception (Exception, throwIO)
import System.Directory (findExecutable)
import System.Environment (lookupEnv)
import System.Info (os)
import System.Process (callCommand, showCommandForUser)


{- | Exception thrown by 'openInBrowser' if can't find a
browser. Stores the current OS inside.

@since 0.0.0.0
-}
newtype BrowseException
= BrowserNotFoundException String
deriving stock (Show)
deriving newtype (Eq)
deriving anyclass (Exception)


{- | Open a given file in a browser. The function has the following algorithm:

* Check the @BROWSER@ environment variable
* If it's not set, try to guess browser depending on OS
* If unsuccsessful, print a message

__Throws:__ 'BrowseException' if can't find a browser.

@since 0.0.0.0
-}
openInBrowser :: FilePath -> IO ()
openInBrowser file = lookupEnv "BROWSER" >>= \case
Just browser -> runCommand browser [file]
Nothing -> case os of
"darwin" -> runCommand "open" [file]
"mingw32" -> runCommand "cmd" ["/c", "start", file]
curOs -> do
browserExe <- findFirstExecutable
[ "xdg-open"
, "cygstart"
, "x-www-browser"
, "firefox"
, "opera"
, "mozilla"
, "netscape"
]
case browserExe of
Just browser -> runCommand browser [file]
Nothing -> throwIO $ BrowserNotFoundException curOs

-- | Execute a command with arguments.
runCommand :: FilePath -> [String] -> IO ()
runCommand cmd args = do
let cmdStr = showCommandForUser cmd args
putStrLn $ "⚙ " ++ cmdStr
callCommand cmdStr

findFirstExecutable :: [FilePath] -> IO (Maybe FilePath)
findFirstExecutable = \case
[] -> pure Nothing
exe:exes -> findExecutable exe >>= \case
Nothing -> findFirstExecutable exes
Just path -> pure $ Just path

{-
------------------------
-- Original source code:
------------------------

{- |
Copyright: (c) 2020 Kowainik
SPDX-License-Identifier: MPL-2.0
Maintainer: Kowainik <[email protected]>

Contains implementation of a function that opens a given file in a
browser.
-}

module Stan.Browse
( openBrowser
) where

import Colourista (errorMessage, infoMessage)
import System.Directory (findExecutable)
import System.Info (os)
import System.Process (callCommand, showCommandForUser)


{- | Open a given file in a browser. The function has the following algorithm:

* Check the @BROWSER@ environment variable
* If it's not set, try to guess browser depending on OS
* If unsuccsessful, print a message
-}
openBrowser :: FilePath -> IO ()
openBrowser file = lookupEnv "BROWSER" >>= \case
Just browser -> runCommand browser [file]
Nothing -> case os of
"darwin" -> runCommand "open" [file]
"mingw32" -> runCommand "cmd" ["/c", "start", file]
curOs -> do
browserExe <- findFirstExecutable
[ "xdg-open"
, "cygstart"
, "x-www-browser"
, "firefox"
, "opera"
, "mozilla"
, "netscape"
]
case browserExe of
Just browser -> runCommand browser [file]
Nothing -> do
errorMessage $ "Cannot guess browser for the OS: " <> toText curOs
infoMessage "Please set the $BROWSER environment variable to a web launcher"
exitFailure

-- | Execute a command with arguments.
runCommand :: FilePath -> [String] -> IO ()
runCommand cmd args = do
let cmdStr = showCommandForUser cmd args
putStrLn $ "⚙ " ++ cmdStr
callCommand cmdStr

findFirstExecutable :: [FilePath] -> IO (Maybe FilePath)
findFirstExecutable = \case
[] -> pure Nothing
exe:exes -> findExecutable exe >>= \case
Nothing -> findFirstExecutable exes
Just path -> pure $ Just path
-}
20 changes: 20 additions & 0 deletions src/Iris/Cli.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{- |
Module : Iris.Cli
Copyright : (c) 2022 Dmitrii Kovanikov
SPDX-License-Identifier : MPL-2.0
Maintainer : Dmitrii Kovanikov <[email protected]>
Stability : Experimental
Portability : Portable

CLI options parsing.

@since 0.0.0.0
-}

module Iris.Cli
( module Iris.Cli.Browse
, module Iris.Cli.Version
) where

import Iris.Cli.Browse
import Iris.Cli.Version
45 changes: 45 additions & 0 deletions src/Iris/Cli/Browse.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{- |
Module : Iris.Cli.Browse
Copyright : (c) 2022 Dmitrii Kovanikov
SPDX-License-Identifier : MPL-2.0
Maintainer : Dmitrii Kovanikov <[email protected]>
Stability : Experimental
Portability : Portable

CLI options parsing for @--browse@ and @--browse=<FILE_PATH>@.

@since 0.0.0.0
-}

module Iris.Cli.Browse
( browseP
, browseFileP
) where

import qualified Options.Applicative as Opt

{- | A CLI option parse a boolean value if a file needs browsing.

Use 'Iris.Browse.openInBrowser' to open the file of your choice in a
browser.

@since 0.0.0.0
-}
browseP :: String -> Opt.Parser Bool
browseP description = Opt.switch $ mconcat
[ Opt.long "browse"
, Opt.help description
]

{- | A CLI option parser for a 'FilePath' that needs to be open wit

Use 'Iris.Browse.openInBrowser' to open the passed file in a browser.

@since 0.0.0.0
-}
browseFileP :: String -> Opt.Parser FilePath
browseFileP description = Opt.option Opt.str $ mconcat
[ Opt.long "browse"
, Opt.metavar "FILE_PATH"
, Opt.help description
]
74 changes: 74 additions & 0 deletions src/Iris/Cli/Version.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
{- |
Module : Iris.Cli.Version
Copyright : (c) 2022 Dmitrii Kovanikov
SPDX-License-Identifier : MPL-2.0
Maintainer : Dmitrii Kovanikov <[email protected]>
Stability : Experimental
Portability : Portable

CLI options parsing for @--version@ and @--numeric-version@

**Enabled with config**

@since 0.0.0.0
-}

module Iris.Cli.Version
( -- * Settings
VersionSettings (..)
, defaultVersionSettings

-- * CLI parser
, fullVersionP

-- * Internal helpers
, mkVersionParser
) where

import Data.Version (Version, showVersion)

import qualified Options.Applicative as Opt


{- |

@since 0.0.0.0
-}
data VersionSettings = VersionSettings
{ -- | @since 0.0.0.0
versionSettingsVersion :: Version

-- | @since 0.0.0.0
, versionSettingsMkDesc :: String -> String
}

{- |

@since 0.0.0.0
-}
defaultVersionSettings :: Version -> VersionSettings
defaultVersionSettings version = VersionSettings
{ versionSettingsVersion = version
, versionSettingsMkDesc = id
}

mkVersionParser :: Maybe VersionSettings -> Opt.Parser (a -> a)
mkVersionParser = maybe (pure id) fullVersionP

fullVersionP :: VersionSettings -> Opt.Parser (a -> a)
fullVersionP VersionSettings{..} = versionP <*> numericVersionP
where
versionStr :: String
versionStr = showVersion versionSettingsVersion

versionP :: Opt.Parser (a -> a)
versionP = Opt.infoOption (versionSettingsMkDesc versionStr) $ mconcat
[ Opt.long "version"
, Opt.help "Show application version"
]

numericVersionP :: Opt.Parser (a -> a)
numericVersionP = Opt.infoOption versionStr $ mconcat
[ Opt.long "numeric-version"
, Opt.help "Show only numeric application version"
]
Loading