{- | Copyright: (c) 2020 Kowainik SPDX-License-Identifier: MPL-2.0 Maintainer: Kowainik 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