diff options
| author | Akshay Nair <phenax5@gmail.com> | 2025-10-05 23:32:17 +0530 |
|---|---|---|
| committer | Akshay Nair <phenax5@gmail.com> | 2025-10-08 13:08:32 +0530 |
| commit | 41d8a90746cd97d1dcb8228c1e9a0846ba9d9b6a (patch) | |
| tree | 942f95367163ad967323ba41f8a400b654e99688 /lib/Daffm/Action/Core.hs | |
| parent | 424d65e53b99c65f07f36578e3d0975c4d093c0e (diff) | |
| download | daffm-41d8a90746cd97d1dcb8228c1e9a0846ba9d9b6a.tar.gz daffm-41d8a90746cd97d1dcb8228c1e9a0846ba9d9b6a.zip | |
Add search command
Diffstat (limited to 'lib/Daffm/Action/Core.hs')
| -rw-r--r-- | lib/Daffm/Action/Core.hs | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/lib/Daffm/Action/Core.hs b/lib/Daffm/Action/Core.hs index a8dad32..a726c77 100644 --- a/lib/Daffm/Action/Core.hs +++ b/lib/Daffm/Action/Core.hs @@ -13,6 +13,7 @@ import Daffm.Types (AppEvent, AppState (..), FileInfo (..), FilePathText, FileTy import Data.Maybe (fromMaybe) import qualified Data.Set as Set import qualified Data.Text as Text +import qualified Data.Vector as Vec import System.Directory (getHomeDirectory) import qualified System.Exit as Proc import System.FilePath (takeDirectory) @@ -24,6 +25,7 @@ modifyM f = get >>= f >>= put loadDir :: FilePathText -> AppEvent () loadDir dir = do modifyM (liftIO . (>>= filterInvalidSelections) . loadDirToState dir) + applySearch reloadDir :: AppEvent () reloadDir = do @@ -93,9 +95,7 @@ currentFile = do toggleCurrentFileSelection :: AppEvent () toggleCurrentFileSelection = do - currentFile >>= \case - Just file -> modify $ toggleFileSelection (filePath file) - Nothing -> pure () + currentFile >>= maybe (pure ()) (modify . toggleFileSelection . filePath) moveCurrent 1 clearFileSelections :: AppEvent () @@ -106,3 +106,46 @@ moveCurrent :: Int -> AppEvent () moveCurrent count = do files <- gets stateFiles modify $ \s -> s {stateFiles = L.listMoveBy count files} + +setSearchTerm :: Text.Text -> AppEvent () +setSearchTerm "" = modify (\st -> st {stateSearchTerm = Nothing, stateSearchIndex = 0}) +setSearchTerm term = modify (\st -> st {stateSearchTerm = Just term, stateSearchIndex = 0}) + +applySearch :: AppEvent () +applySearch = get >>= apply + where + apply :: AppState -> AppEvent () + apply (AppState {stateSearchTerm = Nothing}) = + modify + (\st -> st {stateSearchMatches = Vec.empty, stateSearchIndex = 0}) + apply (AppState {stateSearchTerm = Just term, stateFiles}) = do + let search (_, FileInfo {fileName}) = Text.toLower term `Text.isInfixOf` Text.toLower fileName + let matches = Vec.map fst . Vec.filter search . Vec.indexed $ L.listElements stateFiles + modify + ( \st -> + st + { stateSearchMatches = matches, + stateSearchIndex = wrapSearchIndex st (stateSearchIndex st) + } + ) + +nextSearchMatch :: AppEvent () +nextSearchMatch = do + st@(AppState {stateSearchMatches, stateFiles, stateSearchIndex}) <- get + let nextFiles = + if Vec.null stateSearchMatches + then stateFiles + else L.listMoveTo (stateSearchMatches Vec.! wrapSearchIndex st stateSearchIndex) stateFiles + modify (\st' -> st' {stateFiles = nextFiles}) + +wrapSearchIndex :: AppState -> Int -> Int +wrapSearchIndex (AppState {stateSearchMatches}) nextIndex = + let matchCount = length stateSearchMatches + in if + | nextIndex < 0 -> matchCount - 1 + | nextIndex >= matchCount && matchCount /= 0 -> nextIndex `mod` matchCount + | otherwise -> nextIndex + +updateSearchIndex :: (Int -> Int) -> AppEvent () +updateSearchIndex upd = + modify (\st -> st {stateSearchIndex = wrapSearchIndex st $ upd $ stateSearchIndex st}) |
