aboutsummaryrefslogtreecommitdiff
path: root/lib/Daffm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Daffm')
-rw-r--r--lib/Daffm/Attrs.hs12
-rw-r--r--lib/Daffm/State.hs8
-rw-r--r--lib/Daffm/Types.hs2
-rw-r--r--lib/Daffm/View.hs51
4 files changed, 50 insertions, 23 deletions
diff --git a/lib/Daffm/Attrs.hs b/lib/Daffm/Attrs.hs
index f1d4e16..925fe99 100644
--- a/lib/Daffm/Attrs.hs
+++ b/lib/Daffm/Attrs.hs
@@ -9,6 +9,15 @@ import qualified Graphics.Vty as V
fileAttr :: A.AttrName
fileAttr = listAttr <> A.attrName "file"
+fileTypeAttr :: A.AttrName
+fileTypeAttr = listAttr <> A.attrName "file-type"
+
+fileModeAttr :: A.AttrName
+fileModeAttr = listAttr <> A.attrName "file-mode"
+
+fileOwnerAttr :: A.AttrName
+fileOwnerAttr = listAttr <> A.attrName "file-owner"
+
fileSelectedAttr :: A.AttrName
fileSelectedAttr = listSelectedAttr <> fileAttr
@@ -42,6 +51,9 @@ appAttrMap =
(linkAttr, fg V.brightWhite),
(invalidLinkAttr, fg V.red),
(fileAttr, fg V.white),
+ (fileTypeAttr, fg V.white),
+ (fileOwnerAttr, (fg V.white) { V.attrStyle = V.SetTo V.dim }),
+ (fileModeAttr, fg V.white),
(fileSelectedAttr, fg V.white),
(searchMarchAttr, fg V.magenta)
]
diff --git a/lib/Daffm/State.hs b/lib/Daffm/State.hs
index 1334327..106fee5 100644
--- a/lib/Daffm/State.hs
+++ b/lib/Daffm/State.hs
@@ -19,8 +19,8 @@ import qualified Data.Text.Zipper.Generic as Zipper
import qualified Data.Vector as Vec
import System.Directory (doesPathExist, getCurrentDirectory, getHomeDirectory, getPermissions, getSymbolicLinkTarget, listDirectory, makeAbsolute, readable, setCurrentDirectory)
import System.FilePath (joinPath, takeDirectory)
-import System.PosixCompat (fileExist)
import qualified System.PosixCompat as Posix
+import qualified System.Posix.User as Posix
mkEditor :: (Zipper.GenericTextZipper a) => a -> Editor.Editor a FocusTarget
mkEditor = Editor.editor FocusCmdline (Just 1)
@@ -137,12 +137,16 @@ getFileInfo name = do
if
| Posix.isSymbolicLink stat -> Just . Text.pack <$> getSymbolicLinkTarget path
| otherwise -> pure Nothing
+ user <- Posix.getUserEntryForID $ Posix.fileOwner stat
+ group <- Posix.getGroupEntryForID $ Posix.fileGroup stat
pure $
FileInfo
{ filePath = Text.pack path,
fileName = name,
fileSize = Posix.fileSize stat,
fileMode = Posix.fileMode stat,
+ fileUser = Text.pack . Posix.userName $ user,
+ fileGroup = Text.pack . Posix.groupName $ group,
fileType = fileTypeFromStatus stat,
fileLinkType = fileTypeFromStatus <$> linkStat,
fileLinkTarget = linkTarget
@@ -179,5 +183,5 @@ cacheDirPosition appState@(AppState {stateListPositionHistory, stateCwd, stateFi
filterInvalidSelections :: AppState -> IO AppState
filterInvalidSelections st = do
- selections <- filterM (fileExist . Text.unpack) . Set.elems $ stateFileSelections st
+ selections <- filterM (Posix.fileExist . Text.unpack) . Set.elems $ stateFileSelections st
pure $ st {stateFileSelections = Set.fromList selections}
diff --git a/lib/Daffm/Types.hs b/lib/Daffm/Types.hs
index 0b22816..a1095d4 100644
--- a/lib/Daffm/Types.hs
+++ b/lib/Daffm/Types.hs
@@ -30,6 +30,8 @@ data FileInfo = FileInfo
fileSize :: FileOffset,
fileMode :: FileMode,
fileType :: FileType,
+ fileUser :: Text.Text,
+ fileGroup :: Text.Text,
fileLinkType :: Maybe FileType,
fileLinkTarget :: Maybe FilePathText
}
diff --git a/lib/Daffm/View.hs b/lib/Daffm/View.hs
index 0846f66..01488af 100644
--- a/lib/Daffm/View.hs
+++ b/lib/Daffm/View.hs
@@ -4,7 +4,7 @@ import Brick.Types (Context (availWidth), Size (Fixed), Widget (Widget, render),
import Brick.Widgets.Core (Padding (Max, Pad), TextWidth (textWidth), emptyWidget, hBox, hLimit, padLeft, padRight, str, txt, vBox, vLimit, withAttr, (<+>))
import Brick.Widgets.Edit (renderEditor)
import qualified Brick.Widgets.List as L
-import Daffm.Attrs (directoryAttr, directoryLinkAttr, directorySelectedAttr, fileAttr, fileSelectedAttr, invalidLinkAttr, linkAttr, searchMarchAttr)
+import Daffm.Attrs
import Daffm.Keymap (showKeySequence)
import Daffm.Types (AppState (..), FileInfo (..), FileType (..), FocusTarget (..))
import Data.Int (Int64)
@@ -16,19 +16,20 @@ import qualified System.PosixCompat as Posix
import Text.Printf (printf)
appView :: AppState -> [Widget FocusTarget]
-appView appState@(AppState {stateFiles}) = [ui]
- where
- ui = vBox [vLimit 1 header, box, message, vLimit 1 cmdline]
- header = headerView appState
- cmdline = cmdlineView appState
- message = messageView appState
- box = L.renderListWithIndex (fileItemView appState) True stateFiles
+appView appState =
+ [ vBox
+ [ headerView appState,
+ fileListView appState,
+ messageView appState,
+ vLimit 1 $ cmdlineView appState
+ ]
+ ]
hFixed :: Int -> Widget n -> Widget n
hFixed w = hLimit w . padRight Max
headerView :: AppState -> Widget n
-headerView (AppState {stateCwd}) = Widget Fixed Fixed $ do
+headerView (AppState {stateCwd}) = vLimit 1 $ Widget Fixed Fixed $ do
c <- getContext
let width = availWidth c - 2 -- with padding
render . toWidget . trunc width $ stateCwd
@@ -38,33 +39,39 @@ headerView (AppState {stateCwd}) = Widget Fixed Fixed $ do
| width < textWidth text = "…" <> Text.takeEnd (width - 1) text
| otherwise = Text.takeEnd width text
+fileListView :: AppState -> Widget FocusTarget
+fileListView appState@(AppState {stateFiles}) =
+ L.renderListWithIndex (fileItemView appState) True stateFiles
+
fileItemView :: AppState -> Int -> Bool -> FileInfo -> Widget FocusTarget
-fileItemView appState index sel fileInfo@(FileInfo {filePath, fileSize, fileType, fileMode}) =
+fileItemView appState index sel fileInfo@(FileInfo {filePath, fileSize, fileType, fileMode, fileUser, fileGroup}) =
hBox
[ hFixed 2 fileSelectionView,
+ hFixed 1 $ fileTypeView fileType,
hFixed 10 $ fileModeView fileMode,
- hFixed 6 $ fileTypeView fileType,
+ hFixed 16 $ fileOwnerView fileUser fileGroup,
hFixed 7 $ fileSizeView fileSize,
fileNameView sel fileInfo,
searchMatchIndicatorView
]
where
fileSizeView = txt . prettyFileSize . fromIntegral
- fileTypeView = txt . showFileType
- fileModeView = txt . showFileMode
+ fileTypeView = withAttr fileTypeAttr . txt . showFileType
+ fileModeView = withAttr fileModeAttr . txt . showFileMode
+ fileOwnerView user group = withAttr fileOwnerAttr . txt $ user <> ":" <> group
fileSelectionView = txt $ if Set.member filePath $ stateFileSelections appState then ">" else " "
searchMatchIndicatorView
| index `Vec.elem` stateSearchMatches appState = padLeft (Pad 1) $ withAttr searchMarchAttr $ txt "*"
| otherwise = emptyWidget
showFileType :: FileType -> Text.Text
-showFileType Directory = "dir"
-showFileType SymbolicLink = "link"
-showFileType UnixSocket = "sock"
-showFileType NamedPipe = "pipe"
-showFileType CharacterDevice = "cdev"
-showFileType BlockDevice = "bdev"
-showFileType RegularFile = "file"
+showFileType Directory = "d"
+showFileType SymbolicLink = "l"
+showFileType UnixSocket = "s"
+showFileType NamedPipe = "p"
+showFileType CharacterDevice = "c"
+showFileType BlockDevice = "b"
+showFileType RegularFile = "-"
showFileType UnknownFileType = "?"
showFileMode :: FileMode -> Text.Text
@@ -108,7 +115,9 @@ messageView _ = emptyWidget
cmdlineView :: AppState -> Widget FocusTarget
cmdlineView (AppState {stateFocusTarget = FocusCmdline, stateCmdlineEditor}) =
- txt ":" <+> renderEditor (txt . Text.unlines) True stateCmdlineEditor
+ txt ":" <+> editor
+ where
+ editor = renderEditor (txt . Text.unlines) True stateCmdlineEditor
cmdlineView (AppState {stateFocusTarget = FocusMain, stateFiles, stateFileSelections, stateKeySequence}) =
hBox
[ txt ":",