packages feed

clifm-0.3.1.0: src/Main.hs

module Main where
import Types
import Widgets.Manager
import Widgets.Tab (Tab)

import Options.Applicative
import System.Directory (doesDirectoryExist, doesFileExist, makeAbsolute)
import Data.Semigroup ((<>))
import Control.Monad (void)
import Brick.Main (customMain, showFirstCursor, App(..))
import Brick.Themes (Theme, themeToAttrMap, loadCustomizations)
import Brick.AttrMap (AttrMap)
import Brick.BChan (newBChan)
import Graphics.Vty (mkVty, standardIOConfig, setMode, outputIface, Mode(Mouse))

-- entry point: parses the arguments and starts the brick application

-- options
data FMOptions = FMOptions {dirPath :: FilePath, editComm :: String, themeType :: ThemeType}
data ThemeType = CustomTheme FilePath | DefaultTheme

-- argument parsing functions
opts :: Parser FMOptions
opts = FMOptions
  <$> strOption
    ( long "dir-path"
    <> short 'd'
    <> metavar "FILEPATH"
    <> help "Directory to open"
    <> showDefault
    <> value ".")
  <*> strOption
    ( long "editor"
    <> short 'e'
    <> help "Editor command/path (file path will be appended to this)"
    <> showDefault
    <> value "nano")
  <*> (customTheme <|> defTheme)

customTheme :: Parser ThemeType
customTheme = CustomTheme <$> strOption
  (  long "theme"
  <> short 't'
  <> metavar "FILEPATH"
  <> help "Load a custom theme from an INI file" )

defTheme :: Parser ThemeType
defTheme = flag DefaultTheme DefaultTheme
  ( long "default-theme"
  <> short 'd'
  <> help "Use the default theme" )

main :: IO ()
main = runUI =<< execParser options
  where
    options = info (opts <**> helper)
      ( fullDesc
     <> header "Command Line Interface File Manager"
     <> progDesc "A simple CLI-based File Manager" )

runUI :: FMOptions -> IO ()
runUI options = do
  isDir <- doesDirectoryExist $ dirPath options
  path <- if isDir then makeAbsolute $ dirPath options else return []
  theme <- loadTheme $ themeType options
  let atrm = themeToAttrMap theme
      buildVty = do
        v <- mkVty =<< standardIOConfig
        setMode (outputIface v) Mouse True
        return v
  eventChan <- Brick.BChan.newBChan 10
  state <- makeState path (editComm options) eventChan
  void $ customMain buildVty (Just eventChan) (app atrm) state

app :: AttrMap -> App State (ThreadEvent Tab) Name
app atrm = App { appDraw = drawUi,
    appStartEvent = return,
    appHandleEvent = handleEvent,
    appAttrMap = const atrm,
    appChooseCursor = showFirstCursor
  }

loadTheme :: ThemeType -> IO Theme
loadTheme selTheme = case selTheme of
  DefaultTheme -> return defaultTheme
  CustomTheme path -> do
    isFile <- doesFileExist path
    if not isFile then return defaultTheme
    else do
      customTheme <- loadCustomizations path defaultTheme
      return $ case customTheme of
        Right theme -> theme
        Left _ -> defaultTheme