diff options
Diffstat (limited to 'lib/Daffm')
| -rw-r--r-- | lib/Daffm/Action/Core.hs | 52 | ||||
| -rw-r--r-- | lib/Daffm/Event.hs | 7 | ||||
| -rw-r--r-- | lib/Daffm/State.hs | 9 | ||||
| -rw-r--r-- | lib/Daffm/Types.hs | 2 | ||||
| -rw-r--r-- | lib/Daffm/View.hs | 11 |
5 files changed, 61 insertions, 20 deletions
diff --git a/lib/Daffm/Action/Core.hs b/lib/Daffm/Action/Core.hs index 48792c4..9fed688 100644 --- a/lib/Daffm/Action/Core.hs +++ b/lib/Daffm/Action/Core.hs @@ -5,10 +5,11 @@ module Daffm.Action.Core where import Brick (suspendAndResume') import qualified Brick.Widgets.List as L -import Control.Monad.State (MonadIO (liftIO), MonadState, get, gets, put) -import Daffm.State (loadDirInAppState) +import Control.Monad.State (MonadIO (liftIO), MonadState, get, gets, modify, put) +import Daffm.State (loadDirInAppState, toggleFileSelection) import Daffm.Types (AppEvent, AppState (..), FileInfo (..), FileType (..)) -import Data.Vector ((!?)) +import qualified Data.Set as Set +import System.Directory (getHomeDirectory) import System.FilePath (takeDirectory) import System.Process (callProcess) @@ -25,21 +26,44 @@ goBackToParentDir = do dir <- gets stateParentDir modifyM (liftIO . loadDirInAppState dir (takeDirectory dir)) +goHome :: AppEvent () +goHome = do + dir <- liftIO getHomeDirectory + modifyM (liftIO . loadDirInAppState dir (takeDirectory dir)) + openSelectedFile :: AppEvent () openSelectedFile = do - appState <- get - let indexM = L.listSelected $ stateFiles appState - let files = L.listElements $ stateFiles appState - case indexM >>= (files !?) of - Just file -> openFile appState file + fileM <- currentFile + case fileM of + Just file -> openFile file Nothing -> pure () - pure () -openFile :: AppState -> FileInfo -> AppEvent () -openFile appState (FileInfo {filePath, fileType = Directory}) = do - modifyM (liftIO . loadDirInAppState filePath (stateCwd appState)) -openFile _appState (FileInfo {filePath, fileType}) = do +openFile :: FileInfo -> AppEvent () +openFile (FileInfo {filePath, fileType = Directory}) = do + (AppState {stateCwd}) <- get + modifyM (liftIO . loadDirInAppState filePath stateCwd) +openFile (FileInfo {filePath, fileType}) = do suspendAndResume' $ do putStrLn $ "Opening " <> show fileType <> ": " <> filePath callProcess "nvim" [filePath] - pure () + +currentFile :: AppEvent (Maybe FileInfo) +currentFile = do + gets (fmap snd . L.listSelectedElement . stateFiles) + +toggleCurrentFileSelection :: AppEvent () +toggleCurrentFileSelection = do + fileM <- currentFile + case fileM of + Just file -> modify $ toggleFileSelection (filePath file) + Nothing -> pure () + moveCurrent 1 + +clearFileSelections :: AppEvent () +clearFileSelections = + modify $ \s -> s {stateFileSelections = Set.empty} + +moveCurrent :: Int -> AppEvent () +moveCurrent count = do + files <- gets stateFiles + modify $ \s -> s {stateFiles = L.listMoveBy count files} diff --git a/lib/Daffm/Event.hs b/lib/Daffm/Event.hs index 8eaf960..247719b 100644 --- a/lib/Daffm/Event.hs +++ b/lib/Daffm/Event.hs @@ -5,8 +5,8 @@ import qualified Brick.Types as T import qualified Brick.Widgets.Edit as Editor import qualified Brick.Widgets.List as L import Control.Monad.State (gets, modify) -import Daffm.Action.Cmdline (enterCmdline, evaluateCommand, leaveCmdline, runCmdline, setCmdlineText) -import Daffm.Action.Core (goBackToParentDir, openSelectedFile, reloadDir) +import Daffm.Action.Cmdline +import Daffm.Action.Core import Daffm.State (cacheDirPosition) import Daffm.Types (AppEvent, AppState (..), FocusTarget (..)) import qualified Graphics.Vty as V @@ -19,10 +19,13 @@ appEvent brickevent@(T.VtyEvent event) = do (FocusMain, V.EvKey (V.KChar 'h') []) -> goBackToParentDir (FocusMain, V.EvKey V.KEnter []) -> openSelectedFile (FocusMain, V.EvKey V.KBS []) -> goBackToParentDir + (FocusMain, V.EvKey (V.KChar '~') []) -> goHome (FocusMain, V.EvKey (V.KChar ':') []) -> enterCmdline (FocusMain, V.EvKey (V.KChar '!') []) -> setCmdlineText "!" >> enterCmdline (FocusMain, V.EvKey (V.KChar 'q') []) -> M.halt (FocusMain, V.EvKey (V.KChar 'r') [V.MCtrl]) -> reloadDir + (FocusMain, V.EvKey (V.KChar 'v') []) -> toggleCurrentFileSelection + (FocusMain, V.EvKey (V.KChar 'C') []) -> clearFileSelections -- Just for testing (FocusMain, V.EvKey (V.KChar 'p') [V.MCtrl]) -> evaluateCommand "!!chafa -f kitty %" (FocusCmdline, V.EvKey V.KEsc []) -> leaveCmdline diff --git a/lib/Daffm/State.hs b/lib/Daffm/State.hs index 3990ac0..ead5209 100644 --- a/lib/Daffm/State.hs +++ b/lib/Daffm/State.hs @@ -9,6 +9,7 @@ import Data.Char (toLower) import Data.List (findIndex, sortBy) import qualified Data.Map.Strict as Map import Data.Maybe (fromMaybe) +import qualified Data.Set as Set import qualified Data.Text.Zipper.Generic as Zipper import qualified Data.Vector as Vec import System.Directory (listDirectory, makeAbsolute, setCurrentDirectory) @@ -24,10 +25,18 @@ mkEmptyAppState = stateCmdlineEditor = mkEditor "", stateFocusTarget = FocusMain, stateListPositionCache = Map.empty, + stateFileSelections = Set.empty, stateCwd = "", stateParentDir = "" } +toggleSetItem :: (Ord a) => a -> Set.Set a -> Set.Set a +toggleSetItem val set = + if val `Set.member` set then Set.delete val set else Set.insert val set + +toggleFileSelection :: FilePath -> AppState -> AppState +toggleFileSelection path st = st {stateFileSelections = toggleSetItem path $ stateFileSelections st} + loadDirInAppState :: FilePath -> FilePath -> AppState -> IO AppState loadDirInAppState dir parentDir appState@(AppState {stateCwd, stateListPositionCache}) = do setCurrentDirectory dir diff --git a/lib/Daffm/Types.hs b/lib/Daffm/Types.hs index 14444f4..882a9de 100644 --- a/lib/Daffm/Types.hs +++ b/lib/Daffm/Types.hs @@ -4,6 +4,7 @@ import Brick (EventM) import qualified Brick.Widgets.Edit as Editor import qualified Brick.Widgets.List as L import qualified Data.Map as Map +import qualified Data.Set as Set import System.Posix.Types (FileMode, FileOffset) data FileType @@ -31,6 +32,7 @@ data FocusTarget = FocusCmdline | FocusMain deriving (Show, Eq, Ord) data AppState = AppState { stateFiles :: L.List FocusTarget FileInfo, stateCmdlineEditor :: CmdlineEditor, + stateFileSelections :: Set.Set FilePath, stateFocusTarget :: FocusTarget, stateCwd :: FilePath, stateListPositionCache :: Map.Map String Int, diff --git a/lib/Daffm/View.hs b/lib/Daffm/View.hs index 906fe26..9e0294d 100644 --- a/lib/Daffm/View.hs +++ b/lib/Daffm/View.hs @@ -7,6 +7,7 @@ import qualified Brick.Widgets.List as L import Daffm.Attrs (directoryAttr, directorySelectedAttr, fileAttr, fileSelectedAttr) import Daffm.Types (AppState (..), FileInfo (..), FileType (..), FocusTarget (..)) import Data.Int (Int64) +import qualified Data.Set as Set import qualified Data.Vector as Vec import System.Posix.Types (FileMode) import qualified System.PosixCompat as Posix @@ -18,7 +19,7 @@ appView appState@(AppState {stateFiles}) = [ui] ui = vBox [vLimit 1 header, box, vLimit 1 cmdline] header = headerView appState cmdline = cmdlineView appState - box = L.renderList fileItemView True stateFiles + box = L.renderList (fileItemView appState) True stateFiles hFixed :: Int -> Widget n -> Widget n hFixed w = hLimit w . padRight Max @@ -26,10 +27,11 @@ hFixed w = hLimit w . padRight Max headerView :: AppState -> Widget n headerView (AppState {stateCwd}) = str stateCwd -fileItemView :: Bool -> FileInfo -> Widget FocusTarget -fileItemView sel fileInfo@(FileInfo {fileSize, fileType, fileMode}) = +fileItemView :: AppState -> Bool -> FileInfo -> Widget FocusTarget +fileItemView appState sel fileInfo@(FileInfo {filePath, fileSize, fileType, fileMode}) = hBox - [ hFixed 10 $ fileModeView fileMode, + [ hFixed 2 fileSelectionView, + hFixed 10 $ fileModeView fileMode, hFixed 6 $ fileTypeView fileType, hFixed 7 $ fileSizeView fileSize, fileNameView sel fileInfo @@ -38,6 +40,7 @@ fileItemView sel fileInfo@(FileInfo {fileSize, fileType, fileMode}) = fileSizeView = str . prettyFileSize . fromIntegral fileTypeView = str . showFileType fileModeView = str . showFileMode + fileSelectionView = str $ if Set.member filePath $ stateFileSelections appState then ">" else " " showFileType :: FileType -> String showFileType Directory = "dir" |
