aboutsummaryrefslogtreecommitdiff
path: root/lib/Daffm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Daffm')
-rw-r--r--lib/Daffm/Attrs.hs22
-rw-r--r--lib/Daffm/Types.hs8
-rw-r--r--lib/Daffm/View.hs75
3 files changed, 86 insertions, 19 deletions
diff --git a/lib/Daffm/Attrs.hs b/lib/Daffm/Attrs.hs
index 93a4163..77f9ee6 100644
--- a/lib/Daffm/Attrs.hs
+++ b/lib/Daffm/Attrs.hs
@@ -1,17 +1,31 @@
module Daffm.Attrs where
import qualified Brick.AttrMap as A
-import Brick.Util (fg)
+import Brick.Util (bg, fg)
+import Brick.Widgets.List (listAttr, listSelectedAttr)
import qualified Brick.Widgets.List as L
import qualified Graphics.Vty as V
-selectedFileAttr :: A.AttrName
-selectedFileAttr = A.attrName "selected-file"
+fileAttr :: A.AttrName
+fileAttr = listAttr <> A.attrName "file"
+
+fileSelectedAttr :: A.AttrName
+fileSelectedAttr = listSelectedAttr <> fileAttr
+
+directoryAttr :: A.AttrName
+directoryAttr = listAttr <> A.attrName "directory"
+
+directorySelectedAttr :: A.AttrName
+directorySelectedAttr = listSelectedAttr <> directoryAttr
appAttrMap :: A.AttrMap
appAttrMap =
A.attrMap
V.defAttr
[ (L.listAttr, fg V.white),
- (selectedFileAttr, fg V.cyan)
+ (listSelectedAttr, bg V.black),
+ (directoryAttr, fg V.brightCyan),
+ (directorySelectedAttr, fg V.brightCyan),
+ (fileAttr, fg V.white),
+ (fileSelectedAttr, fg V.white)
]
diff --git a/lib/Daffm/Types.hs b/lib/Daffm/Types.hs
index 2a8e97d..5462851 100644
--- a/lib/Daffm/Types.hs
+++ b/lib/Daffm/Types.hs
@@ -1,5 +1,6 @@
module Daffm.Types where
+import qualified Brick.Widgets.Edit as Editor
import qualified Brick.Widgets.List as L
import System.Posix.Types (FileOffset)
@@ -21,8 +22,13 @@ data FileInfo = FileInfo
}
deriving (Show)
+data FocusTarget = FocusCmdline | FocusMain deriving (Show, Eq, Ord)
+
data AppState = AppState
- { stateFiles :: L.List () FileInfo,
+ { stateFiles :: L.List FocusTarget FileInfo,
+ stateCmdlineEditor :: Editor.Editor String FocusTarget,
+ stateFocusTarget :: FocusTarget,
+ -- stateFocusRing :: FocusRing FocusTarget,
stateCwd :: FilePath,
stateParentDir :: FilePath
}
diff --git a/lib/Daffm/View.hs b/lib/Daffm/View.hs
index 02529ac..db26a7d 100644
--- a/lib/Daffm/View.hs
+++ b/lib/Daffm/View.hs
@@ -1,25 +1,72 @@
module Daffm.View where
import Brick.Types (Widget)
-import Brick.Widgets.Core (str, vBox, vLimit, withAttr, (<+>))
+import Brick.Widgets.Core (Padding (Max, Pad), TextWidth (textWidth), hBox, hLimit, padLeft, padRight, str, vBox, vLimit, withAttr, (<+>))
+import Brick.Widgets.Edit (renderEditor)
import qualified Brick.Widgets.List as L
-import Daffm.Attrs (selectedFileAttr)
-import Daffm.Types (AppState (..), FileInfo (..))
+import Daffm.Attrs (directoryAttr, directorySelectedAttr, fileAttr, fileSelectedAttr)
+import Daffm.Types (AppState (..), FileInfo (..), FileType (..), FocusTarget (..))
+import Data.Int (Int64)
import qualified Data.Vector as Vec
+import Text.Printf (printf)
-appView :: AppState -> [Widget ()]
-appView (AppState {stateFiles, stateCwd}) = [ui]
+appView :: AppState -> [Widget FocusTarget]
+appView appState@(AppState {stateFiles, stateCwd}) = [ui]
where
+ ui :: Widget FocusTarget
ui = vBox [vLimit 1 header, box, vLimit 1 cmdline]
header = str stateCwd
- cmdline = str "Item " <+> cur <+> str " of " <+> total
- cur = case L.listSelected stateFiles of
- Nothing -> str "-"
- Just i -> str (show (i + 1))
- total = str $ show $ Vec.length $ L.listElements stateFiles
+ cmdline = cmdlineView appState
+ box :: Widget FocusTarget
box = L.renderList fileItemView True stateFiles
-fileItemView :: Bool -> FileInfo -> Widget ()
-fileItemView sel (FileInfo {fileName, fileSize, fileType}) =
- let wrap w = if sel then withAttr selectedFileAttr w else w
- in wrap (str fileName) <+> str (" : " <> show fileSize <> " | " <> show fileType)
+fixedColumnsStr :: Int -> Widget n -> Widget n
+fixedColumnsStr w s = hLimit w $ padRight Max s
+
+fileItemView :: Bool -> FileInfo -> Widget FocusTarget
+fileItemView sel fileInfo@(FileInfo {fileSize, fileType}) =
+ hBox
+ [ fixedColumnsStr 5 (fileTypeView fileType),
+ fixedColumnsStr 7 (fileSizeView fileSize),
+ fileNameView sel fileInfo
+ ]
+ where
+ fileSizeView = str . prettyFileSize . fromIntegral
+ fileTypeView = str . showFileType
+ showFileType Directory = "dir"
+ showFileType SymbolicLink = "link"
+ showFileType UnixSocket = "sock"
+ showFileType NamedPipe = "pipe"
+ showFileType CharacterDevice = "cdev"
+ showFileType BlockDevice = "bdev"
+ showFileType RegularFile = "file"
+
+fileNameView :: Bool -> FileInfo -> Widget FocusTarget
+fileNameView True (FileInfo {fileName, fileType = Directory}) = withAttr directorySelectedAttr $ str $ fileName <> "/"
+fileNameView False (FileInfo {fileName, fileType = Directory}) = withAttr directoryAttr $ str $ fileName <> "/"
+fileNameView True (FileInfo {fileName}) = withAttr fileSelectedAttr $ str fileName
+fileNameView False (FileInfo {fileName}) = withAttr fileAttr $ str fileName
+
+cmdlineView :: AppState -> Widget FocusTarget
+cmdlineView (AppState {stateFocusTarget = FocusCmdline, stateCmdlineEditor}) =
+ str ":" <+> renderEditor (str . unlines) True stateCmdlineEditor
+cmdlineView (AppState {stateFiles}) =
+ hBox [str ":", padLeft Max $ padRight (Pad 1) posIndicator]
+ where
+ posIndicator = str $ cur <> "/" <> total
+ cur = case L.listSelected stateFiles of
+ Nothing -> "-"
+ Just n -> show (n + 1)
+ total = show $ Vec.length $ L.listElements stateFiles
+
+prettyFileSize :: Int64 -> String
+prettyFileSize i
+ | i >= 2 ^ (40 :: Int64) = format (i `divBy` (2 ** 40)) <> "T"
+ | i >= 2 ^ (30 :: Int64) = format (i `divBy` (2 ** 30)) <> "G"
+ | i >= 2 ^ (20 :: Int64) = format (i `divBy` (2 ** 20)) <> "M"
+ | i >= 2 ^ (10 :: Int64) = format (i `divBy` (2 ** 10)) <> "K"
+ | otherwise = show i
+ where
+ format = printf "%0.1f"
+ divBy :: Int64 -> Double -> Double
+ divBy a b = (fromIntegral a :: Double) / b