diff options
Diffstat (limited to 'lib/Daffm.hs')
| -rw-r--r-- | lib/Daffm.hs | 128 |
1 files changed, 4 insertions, 124 deletions
diff --git a/lib/Daffm.hs b/lib/Daffm.hs index a7a3705..ffae42b 100644 --- a/lib/Daffm.hs +++ b/lib/Daffm.hs @@ -1,72 +1,11 @@ -module Daffm where +module Daffm (app, loadDirInAppState, mkEmptyAppState) where -import Brick (suspendAndResume') import qualified Brick.Main as M -import qualified Brick.Types as T -import qualified Brick.Widgets.Edit as Editor -import qualified Brick.Widgets.List as L -import Control.Monad (forM) -import Control.Monad.State (MonadIO (liftIO), MonadState, get, gets, modify, put) import Daffm.Attrs (appAttrMap) -import Daffm.Types (AppState (..), FileInfo (..), FileType (..), FocusTarget (FocusCmdline, FocusMain)) +import Daffm.Event (appEvent) +import Daffm.State (loadDirInAppState, mkEmptyAppState) +import Daffm.Types (AppState (..), FocusTarget) import Daffm.View (appView) -import Data.Char (toLower) -import Data.List (sortBy) -import Data.Maybe (fromMaybe) -import Data.Vector ((!?)) -import qualified Data.Vector as Vec -import qualified Graphics.Vty as V -import System.Directory (listDirectory, makeAbsolute, setCurrentDirectory) -import System.FilePath (takeDirectory) -import qualified System.PosixCompat as Posix -import System.Process (callProcess) - -type AppEvent = T.EventM FocusTarget AppState - -modifyM :: (MonadState s m) => (s -> m s) -> m () -modifyM f = get >>= f >>= put - -openSelectedFile :: AppEvent () -openSelectedFile = do - AppState {stateFiles, stateCwd} <- get - let indexM = L.listSelected stateFiles - let files = L.listElements stateFiles - case indexM >>= (files !?) of - Just (FileInfo {filePath, fileType = Directory}) -> - modifyM (liftIO . loadDirInAppState filePath stateCwd) - Just (FileInfo {filePath, fileType}) -> do - suspendAndResume' $ do - callProcess "nvim" [filePath] - putStrLn $ "Opening " <> show fileType <> ": " <> filePath - pure () - Nothing -> pure () - pure () - -goBackToParentDir :: AppEvent () -goBackToParentDir = do - dir <- gets stateParentDir - modifyM (liftIO . loadDirInAppState dir (takeDirectory dir)) - -appEvent :: T.BrickEvent FocusTarget e -> AppEvent () -appEvent brickevent@(T.VtyEvent event) = do - focusTarget <- gets stateFocusTarget - case (focusTarget, event) of - (FocusCmdline, V.EvKey V.KEsc []) -> modify (\st -> st {stateFocusTarget = FocusMain}) - (FocusMain, V.EvKey (V.KChar ':') []) -> modify (\st -> st {stateFocusTarget = FocusCmdline}) - (FocusMain, V.EvKey (V.KChar 'q') []) -> M.halt - (FocusMain, V.EvKey (V.KChar 'l') []) -> openSelectedFile - (FocusMain, V.EvKey (V.KChar 'h') []) -> goBackToParentDir - (FocusMain, V.EvKey V.KEnter []) -> openSelectedFile - (FocusMain, V.EvKey V.KBS []) -> goBackToParentDir - (FocusMain, _) -> do - files <- gets stateFiles - newFiles <- T.nestEventM' files (L.handleListEventVi L.handleListEvent event) - modify (\appState -> appState {stateFiles = newFiles}) - (FocusCmdline, _) -> do - editor <- gets stateCmdlineEditor - newEditor <- T.nestEventM' editor (Editor.handleEditorEvent brickevent) - modify (\appState -> appState {stateCmdlineEditor = newEditor}) -appEvent _ = pure () app :: M.App AppState e FocusTarget app = @@ -77,62 +16,3 @@ app = M.appStartEvent = pure (), M.appAttrMap = const appAttrMap } - -fileTypeFromStatus :: Posix.FileStatus -> Maybe FileType -fileTypeFromStatus s = - if - | Posix.isBlockDevice s -> Just BlockDevice - | Posix.isCharacterDevice s -> Just CharacterDevice - | Posix.isNamedPipe s -> Just NamedPipe - | Posix.isRegularFile s -> Just RegularFile - | Posix.isDirectory s -> Just Directory - | Posix.isSocket s -> Just UnixSocket - | Posix.isSymbolicLink s -> Just SymbolicLink - | otherwise -> Nothing - -getFileInfo :: FilePath -> IO FileInfo -getFileInfo name = do - path <- makeAbsolute name - stat <- Posix.getSymbolicLinkStatus path - pure $ - FileInfo - { filePath = path, - fileName = name, - fileSize = Posix.fileSize stat, - fileType = fromMaybe RegularFile $ fileTypeFromStatus stat - } - -fileSorter :: FileInfo -> FileInfo -> Ordering -fileSorter (FileInfo {fileType = Directory, fileName = fa}) (FileInfo {fileType = Directory, fileName = fb}) = - compare (toLower <$> fa) (toLower <$> fb) -fileSorter (FileInfo {fileType = Directory}) _ = LT -fileSorter _ (FileInfo {fileType = Directory}) = GT -fileSorter (FileInfo {fileName = fa}) (FileInfo {fileName = fb}) = - compare (toLower <$> fa) (toLower <$> fb) - -listFilesInDir :: FilePath -> IO [FileInfo] -listFilesInDir dir = do - files <- listDirectory dir - sortBy fileSorter <$> forM files getFileInfo - -loadDirInAppState :: FilePath -> FilePath -> AppState -> IO AppState -loadDirInAppState dir parentDir appState = do - setCurrentDirectory dir - files <- listFilesInDir dir - pure $ - appState - { stateFiles = L.list FocusMain (Vec.fromList files) 1, - stateCwd = dir, - stateParentDir = parentDir - } - -mkEmptyAppState :: AppState -mkEmptyAppState = - AppState - { stateFiles = L.list FocusMain (Vec.fromList []) 1, - stateCmdlineEditor = Editor.editor FocusCmdline Nothing "", - stateFocusTarget = FocusMain, - -- stateFocusRing = focusRing [FocusMain, FocusCmdline], - stateCwd = "", - stateParentDir = "" - } |
