diff options
Diffstat (limited to 'lib/Daffm')
| -rw-r--r-- | lib/Daffm/Attrs.hs | 12 | ||||
| -rw-r--r-- | lib/Daffm/State.hs | 8 | ||||
| -rw-r--r-- | lib/Daffm/Types.hs | 2 | ||||
| -rw-r--r-- | lib/Daffm/View.hs | 51 |
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 ":", |
