diff options
| author | Akshay Nair <phenax5@gmail.com> | 2025-10-03 20:21:31 +0530 |
|---|---|---|
| committer | Akshay Nair <phenax5@gmail.com> | 2025-10-03 21:10:34 +0530 |
| commit | b1f56e140e6166c06a5b1f0a02aa4bc0953d6eb3 (patch) | |
| tree | 0be94058cb050c1571e0d21f806433def5d3ad49 /lib | |
| parent | 4d669ba5d5858e47b8d5723aae89b75481a2df2f (diff) | |
| download | daffm-b1f56e140e6166c06a5b1f0a02aa4bc0953d6eb3.tar.gz daffm-b1f56e140e6166c06a5b1f0a02aa4bc0953d6eb3.zip | |
Add delete command + minor refactors
Diffstat (limited to '')
| -rw-r--r-- | lib/Daffm.hs | 4 | ||||
| -rw-r--r-- | lib/Daffm/Action/Cmdline.hs | 37 | ||||
| -rw-r--r-- | lib/Daffm/Action/Core.hs | 22 | ||||
| -rw-r--r-- | lib/Daffm/State.hs | 12 |
4 files changed, 48 insertions, 27 deletions
diff --git a/lib/Daffm.hs b/lib/Daffm.hs index ffae42b..afdba11 100644 --- a/lib/Daffm.hs +++ b/lib/Daffm.hs @@ -1,9 +1,9 @@ -module Daffm (app, loadDirInAppState, mkEmptyAppState) where +module Daffm (app, loadDirToState, mkEmptyAppState) where import qualified Brick.Main as M import Daffm.Attrs (appAttrMap) import Daffm.Event (appEvent) -import Daffm.State (loadDirInAppState, mkEmptyAppState) +import Daffm.State (loadDirToState, mkEmptyAppState) import Daffm.Types (AppState (..), FocusTarget) import Daffm.View (appView) diff --git a/lib/Daffm/Action/Cmdline.hs b/lib/Daffm/Action/Cmdline.hs index bf1f3f1..64977aa 100644 --- a/lib/Daffm/Action/Cmdline.hs +++ b/lib/Daffm/Action/Cmdline.hs @@ -3,16 +3,17 @@ module Daffm.Action.Cmdline where import Brick (suspendAndResume') import qualified Brick.Widgets.Edit as Editor import qualified Brick.Widgets.List as L -import Control.Monad (void) +import Control.Monad (unless, void) import Control.Monad.State (get, gets, modify) import Daffm.Action.Core (reloadDir) import Daffm.Types (AppEvent, AppState (..), FileInfo (..), FocusTarget (..)) import Data.Char (isSpace) import Data.List (dropWhileEnd) +import qualified Data.Set as Set import qualified Data.Text as Text import qualified Data.Text.Zipper as Z import qualified Data.Text.Zipper as Zipper -import System.Process (callCommand) +import System.Process (callCommand, callProcess) leaveCmdline :: AppEvent () leaveCmdline = clearCmdline >> modify (\st -> st {stateFocusTarget = FocusMain}) @@ -27,16 +28,6 @@ setCmdlineText text = clearCmdline :: AppEvent () clearCmdline = applyCmdlineEdit Z.clearZipper -cmdSubstitutions :: Text.Text -> AppEvent Text.Text -cmdSubstitutions cmd = do - (AppState {stateFiles, stateCwd}) <- get - let file = maybe "" (filePath . snd) . L.listSelectedElement $ stateFiles - -- TODO: Escaping % - let subst = - Text.replace "%" (Text.pack file) - . Text.replace "%d" (Text.pack stateCwd) - pure . subst $ cmd - runCmdline :: AppEvent () runCmdline = do cmd <- gets (trimCmd . Editor.getEditContents . stateCmdlineEditor) @@ -56,8 +47,30 @@ evaluateCommand ('!' : cmd) = do cmd' <- Text.unpack <$> cmdSubstitutions (Text.pack cmd) suspendAndResume' $ callCommand cmd' reloadDir +evaluateCommand "delete" = do + (AppState {stateFileSelections, stateFiles}) <- get + let files = + if Set.null stateFileSelections + then maybe [] ((: []) . filePath . snd) $ L.listSelectedElement stateFiles + else Set.elems stateFileSelections + unless (null files) $ do + suspendAndResume' $ callProcess "rm" ("-rfi" : files) + reloadDir evaluateCommand _cmd = pure () +cmdSubstitutions :: Text.Text -> AppEvent Text.Text +cmdSubstitutions cmd = do + (AppState {stateFiles, stateCwd, stateFileSelections}) <- get + let file = maybe "" (filePath . snd) . L.listSelectedElement $ stateFiles + let escape = (\s -> "'" <> s <> "'") . Text.replace "'" "\\'" + let selections = Text.unwords . map (escape . Text.pack) $ Set.elems stateFileSelections + -- TODO: Escaping % + let subst = + Text.replace "%" (Text.pack file) + . Text.replace "%d" (Text.pack stateCwd) + . Text.replace "%s" selections + pure . subst $ cmd + applyCmdlineEdit :: (Zipper.TextZipper String -> Zipper.TextZipper String) -> AppEvent () applyCmdlineEdit zipper = do editor <- gets stateCmdlineEditor diff --git a/lib/Daffm/Action/Core.hs b/lib/Daffm/Action/Core.hs index 9fed688..d18bda9 100644 --- a/lib/Daffm/Action/Core.hs +++ b/lib/Daffm/Action/Core.hs @@ -1,12 +1,13 @@ {-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} {-# HLINT ignore "Use for_" #-} +{-# HLINT ignore "Use <=<" #-} module Daffm.Action.Core where import Brick (suspendAndResume') import qualified Brick.Widgets.List as L import Control.Monad.State (MonadIO (liftIO), MonadState, get, gets, modify, put) -import Daffm.State (loadDirInAppState, toggleFileSelection) +import Daffm.State import Daffm.Types (AppEvent, AppState (..), FileInfo (..), FileType (..)) import qualified Data.Set as Set import System.Directory (getHomeDirectory) @@ -16,32 +17,34 @@ import System.Process (callProcess) modifyM :: (MonadState s m) => (s -> m s) -> m () modifyM f = get >>= f >>= put +loadDir :: FilePath -> FilePath -> AppEvent () +loadDir dir parentDir = do + modifyM (liftIO . (>>= filterInvalidSelections) . loadDirToState dir parentDir) + reloadDir :: AppEvent () reloadDir = do AppState {stateCwd, stateParentDir} <- get - modifyM (liftIO . loadDirInAppState stateCwd stateParentDir) + loadDir stateCwd stateParentDir goBackToParentDir :: AppEvent () goBackToParentDir = do dir <- gets stateParentDir - modifyM (liftIO . loadDirInAppState dir (takeDirectory dir)) + loadDir dir (takeDirectory dir) goHome :: AppEvent () goHome = do dir <- liftIO getHomeDirectory - modifyM (liftIO . loadDirInAppState dir (takeDirectory dir)) + loadDir dir (takeDirectory dir) openSelectedFile :: AppEvent () openSelectedFile = do - fileM <- currentFile - case fileM of + currentFile >>= \case Just file -> openFile file Nothing -> pure () openFile :: FileInfo -> AppEvent () openFile (FileInfo {filePath, fileType = Directory}) = do - (AppState {stateCwd}) <- get - modifyM (liftIO . loadDirInAppState filePath stateCwd) + gets stateCwd >>= loadDir filePath openFile (FileInfo {filePath, fileType}) = do suspendAndResume' $ do putStrLn $ "Opening " <> show fileType <> ": " <> filePath @@ -53,8 +56,7 @@ currentFile = do toggleCurrentFileSelection :: AppEvent () toggleCurrentFileSelection = do - fileM <- currentFile - case fileM of + currentFile >>= \case Just file -> modify $ toggleFileSelection (filePath file) Nothing -> pure () moveCurrent 1 diff --git a/lib/Daffm/State.hs b/lib/Daffm/State.hs index ead5209..d35dccf 100644 --- a/lib/Daffm/State.hs +++ b/lib/Daffm/State.hs @@ -3,7 +3,7 @@ module Daffm.State where import qualified Brick.Widgets.Edit as Editor import qualified Brick.Widgets.List as L import Control.Applicative ((<|>)) -import Control.Monad (forM) +import Control.Monad (filterM, forM) import Daffm.Types (AppState (..), FileInfo (..), FileType (..), FocusTarget (..)) import Data.Char (toLower) import Data.List (findIndex, sortBy) @@ -13,6 +13,7 @@ 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) +import System.PosixCompat (fileExist) import qualified System.PosixCompat as Posix mkEditor :: (Zipper.GenericTextZipper a) => a -> Editor.Editor a FocusTarget @@ -37,8 +38,8 @@ toggleSetItem 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 +loadDirToState :: FilePath -> FilePath -> AppState -> IO AppState +loadDirToState dir parentDir appState@(AppState {stateCwd, stateListPositionCache}) = do setCurrentDirectory dir files <- listFilesInDir dir let prevDirPosM = findIndex ((== stateCwd) . filePath) files @@ -97,3 +98,8 @@ cacheDirPosition appState@(AppState {stateListPositionCache, stateCwd, stateFile } where pos = fromMaybe 0 $ L.listSelected stateFiles + +filterInvalidSelections :: AppState -> IO AppState +filterInvalidSelections st = do + selections <- filterM fileExist . Set.elems $ stateFileSelections st + pure $ st {stateFileSelections = Set.fromList selections} |
