(@_@)

This commit is contained in:
pingu 2023-10-16 15:57:45 +02:00
parent 5350a7b2e6
commit 82fe300c87

View File

@ -1,14 +1,16 @@
{-# LANGUAGE BlockArguments #-} {-# LANGUAGE BlockArguments #-}
module Main where module Main where
import System.Posix.Directory ( getWorkingDirectory ) import System.Posix.Directory ( getWorkingDirectory, changeWorkingDirectory )
import System.Directory ( pathIsSymbolicLink import System.Directory ( pathIsSymbolicLink
, doesFileExist , doesFileExist
, getFileSize , getFileSize
, doesDirectoryExist ) , doesDirectoryExist )
import Data.Functor ( (<&>) ) import Data.Functor ( (<&>) )
import Control.Monad ( filterM ) import Control.Monad ( filterM )
import Control.Monad.IO.Class
import System.Directory.Extra ( listContents ) import System.Directory.Extra ( listContents )
import System.IO.Error
import Brick import Brick
import Brick.Widgets.Edit import Brick.Widgets.Edit
import Graphics.Vty import Graphics.Vty
@ -26,14 +28,28 @@ listNonSymDirectories dir = filterM ((not <$>) . pathIsSymbolicLink) =<< filterM
listSym :: FilePath -> IO [FilePath] listSym :: FilePath -> IO [FilePath]
listSym dir = filterM pathIsSymbolicLink =<< listContents dir listSym dir = filterM pathIsSymbolicLink =<< listContents dir
handlePermissionError :: IOError -> IO Integer
handlePermissionError e = if isPermissionError e then pure 0 else ioError e
getSizeSubpaths :: FilePath -> IO [(FilePath, Integer)] getSizeSubpaths :: FilePath -> IO [(FilePath, Integer)]
getSizeSubpaths x = do getSizeSubpaths x = do
sub <- listNonSymDirectories x sub <- listNonSymDirectories x
subby <- mapM (\y -> (y,) . sum . map snd <$> getSizeSubpaths y) sub subby <- mapM
(\y -> (y,) . sum . map snd <$>
getSizeSubpaths y)
sub
syms <- listSym x syms <- listSym x
local <- listNonSymFiles x >>= (\y -> mapM getFileSize y <&> zip y) local <- listNonSymFiles x >>=
(\y -> mapM
(flip catchIOError handlePermissionError . getFileSize) y <&>
zip y)
pure $ sortOn (Data.Ord.Down . snd) $ local ++ subby ++ zip syms [0..0] pure $ sortOn (Data.Ord.Down . snd) $ local ++ subby ++ zip syms [0..0]
data ScrollDirection where
SUp :: ScrollDirection
SDown :: ScrollDirection
data AppS = AppS data AppS = AppS
{ {
_appCWD :: FilePath _appCWD :: FilePath
@ -42,17 +58,10 @@ data AppS = AppS
, _appSubFiles :: [(FilePath, Integer)] , _appSubFiles :: [(FilePath, Integer)]
} }
data ScrollDirection where
SUp :: ScrollDirection
SDown :: ScrollDirection
ui :: Widget ()
ui = viewport () Vertical $ str "Svamp är gott"
app :: App AppS e () app :: App AppS e ()
app = app =
App { appDraw = pure . browse App { appDraw = pure . browse
, appHandleEvent = resizeOrQuit , appHandleEvent = eventHandler
, appStartEvent = pure () , appStartEvent = pure ()
, appAttrMap = attributeMap , appAttrMap = attributeMap
, appChooseCursor = showFirstCursor , appChooseCursor = showFirstCursor
@ -73,9 +82,10 @@ browse s =
viewport () Vertical (foldr (widgetCons s) emptyWidget (_appSubFiles s)) viewport () Vertical (foldr (widgetCons s) emptyWidget (_appSubFiles s))
widgetCons :: AppS -> (FilePath, Integer) -> Widget () -> Widget () widgetCons :: AppS -> (FilePath, Integer) -> Widget () -> Widget ()
widgetCons s w@(f,_) ws = (<=> ws) if Just f == _appFocus s then widgetCons s w@(f,_) ws =
select . visible $ pathWidget w (<=> ws) if Just f == _appFocus s then
else pathWidget w select . visible $ pathWidget w else
pathWidget w
pathWidget :: (FilePath, Integer) -> Widget () pathWidget :: (FilePath, Integer) -> Widget ()
pathWidget (f, s) = str (show f) <+> padLeft Max (str (show s)) pathWidget (f, s) = str (show f) <+> padLeft Max (str (show s))
@ -87,13 +97,25 @@ sizeDir s = do
changeDir :: AppS -> IO AppS changeDir :: AppS -> IO AppS
changeDir so changeDir so
| isJust $ _appFocus so = | isJust $ _appFocus so = do
let s = so { allowed <- doesDirectoryExist path
_appCWD = fromJust $ _appFocus so if allowed then do
, _appSubFiles = [] changeWorkingDirectory path
} in let s =
sizeDir s so {
_appCWD = path
, _appSubFiles = []
} in
sizeDir s else
pure so
| otherwise = pure so | otherwise = pure so
where path = fromJust $ _appFocus so
overDir :: IO AppS
overDir = do
changeWorkingDirectory ".."
a <- getWorkingDirectory
changeDir $ initialState a
scroll :: ScrollDirection -> AppS -> AppS scroll :: ScrollDirection -> AppS -> AppS
scroll d s = s { scroll d s = s {
@ -105,17 +127,41 @@ scroll d s = s {
case d of case d of
SUp -> (-1) SUp -> (-1)
SDown -> 1 SDown -> 1
newCursor = max 0 (min ((-) 1 . length $ _appSubFiles s) cursor) newCursor = max 0 (min (subtract 1 . length $ _appSubFiles s) cursor)
maybeNewPath = fst <$> _appSubFiles s !? newCursor maybeNewPath = fst <$> _appSubFiles s !? newCursor
initialState :: FilePath -> AppS eventHandler :: BrickEvent () e -> EventM () AppS ()
initialState f = AppS { eventHandler (VtyEvent (EvKey k _)) = do
_appCWD = f s <- get
, _appCursor = 0 case k of
, _appFocus = pure f (KChar 'q') -> halt
, _appSubFiles = [] KEsc -> halt
}
(KChar 'j') -> put $ scroll SDown s
(KChar 'k') -> put $ scroll SUp s
KDown -> put $ scroll SDown s
KUp -> put $ scroll SUp s
(KChar 'h') -> put =<< liftIO overDir
KLeft -> put =<< liftIO overDir
(KChar ' ') -> put =<< liftIO (changeDir s)
KEnter -> put =<< liftIO (changeDir s)
(KChar 'l') -> put =<< liftIO (changeDir s)
KRight -> put =<< liftIO (changeDir s)
_ -> continueWithoutRedraw
eventHandler _ = undefined
initialState :: FilePath -> AppS
initialState f =
AppS {
_appCWD = f
, _appCursor = 0
, _appFocus = pure f
, _appSubFiles = []
}
main :: IO () main :: IO ()
main = do main = do