aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAkshay Nair <phenax5@gmail.com>2025-10-03 14:32:44 +0530
committerAkshay Nair <phenax5@gmail.com>2025-10-03 14:32:44 +0530
commitc3eb868c3873af2fc556525350bde6faebbd7cc8 (patch)
treeb289076a0ef9872221ef1a79399aa93236cf2a7b /lib
parentf820f302130445d8b983ab89746f6de7443c0bea (diff)
downloaddaffm-c3eb868c3873af2fc556525350bde6faebbd7cc8.tar.gz
daffm-c3eb868c3873af2fc556525350bde6faebbd7cc8.zip
Add "press key to continue" with !! prefix
Diffstat (limited to 'lib')
-rw-r--r--lib/Daffm/Event.hs40
-rw-r--r--lib/Daffm/State.hs7
-rw-r--r--lib/Daffm/Types.hs7
-rw-r--r--lib/Daffm/View.hs11
4 files changed, 46 insertions, 19 deletions
diff --git a/lib/Daffm/Event.hs b/lib/Daffm/Event.hs
index 96cbe0d..2bcebab 100644
--- a/lib/Daffm/Event.hs
+++ b/lib/Daffm/Event.hs
@@ -5,14 +5,15 @@ import qualified Brick.Main as M
import qualified Brick.Types as T
import qualified Brick.Widgets.Edit as Editor
import qualified Brick.Widgets.List as L
+import Control.Monad (void)
import Control.Monad.State (MonadIO (liftIO), MonadState, get, gets, modify, put)
import Daffm.State (cacheDirPosition, loadDirInAppState)
import Daffm.Types (AppEvent, AppState (..), FileInfo (..), FileType (..), FocusTarget (..))
import Data.Char (isSpace)
import Data.List (dropWhileEnd)
import qualified Data.Text as Text
-import Data.Text.Array (run)
import qualified Data.Text.Zipper as Z
+import qualified Data.Text.Zipper as Zipper
import Data.Vector ((!?))
import qualified Graphics.Vty as V
import System.FilePath (takeDirectory)
@@ -30,8 +31,11 @@ appEvent brickevent@(T.VtyEvent event) = do
(FocusMain, V.EvKey V.KEnter []) -> openSelectedFile
(FocusMain, V.EvKey V.KBS []) -> goBackToParentDir
(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
+ -- Just for testing
+ (FocusMain, V.EvKey (V.KChar 'p') [V.MCtrl]) -> evaluateCommand "!!chafa -f kitty %"
(FocusCmdline, V.EvKey V.KEsc []) -> leaveCmdline
(FocusCmdline, V.EvKey V.KEnter []) -> runCmdline
(FocusMain, _) -> do
@@ -46,19 +50,26 @@ appEvent brickevent@(T.VtyEvent event) = do
appEvent _ = pure ()
leaveCmdline :: AppEvent ()
-leaveCmdline = clearEditor >> modify (\st -> st {stateFocusTarget = FocusMain})
+leaveCmdline = clearCmdline >> modify (\st -> st {stateFocusTarget = FocusMain})
enterCmdline :: AppEvent ()
enterCmdline = modify (\st -> st {stateFocusTarget = FocusCmdline})
+setCmdlineText :: String -> AppEvent ()
+setCmdlineText text =
+ applyCmdlineEdit (const $ Z.stringZipper [text] (Just 1))
+
+clearCmdline :: AppEvent ()
+clearCmdline = applyCmdlineEdit Z.clearZipper
+
cmdSubstitutions :: Text.Text -> AppEvent Text.Text
cmdSubstitutions cmd = do
- appState <- get
- let file = maybe "" (filePath . snd) . L.listSelectedElement . stateFiles $ appState
+ (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 appState)
+ . Text.replace "%d" (Text.pack stateCwd)
pure . subst $ cmd
runCmdline :: AppEvent ()
@@ -70,23 +81,30 @@ runCmdline = do
trimCmd = dropWhile isSpace . dropWhileEnd isSpace . unlines
evaluateCommand :: String -> AppEvent ()
+evaluateCommand ('!' : '!' : cmd) = do
+ cmd' <- Text.unpack <$> cmdSubstitutions (Text.pack cmd)
+ suspendAndResume' $ do
+ callCommand cmd'
+ putStrLn "Press any key to continue"
+ void getChar
+ reloadDir
evaluateCommand ('!' : cmd) = do
cmd' <- Text.unpack <$> cmdSubstitutions (Text.pack cmd)
suspendAndResume' $ callCommand cmd'
reloadDir
evaluateCommand _cmd = pure ()
-clearEditor :: AppEvent ()
-clearEditor = do
- editor <- gets stateCmdlineEditor
- let editor' = Editor.applyEdit Z.clearZipper editor
- modify (\s -> s {stateCmdlineEditor = editor'})
-
reloadDir :: AppEvent ()
reloadDir = do
AppState {stateParentDir, stateCwd} <- get
modifyM (liftIO . loadDirInAppState stateCwd stateParentDir)
+applyCmdlineEdit :: (Zipper.TextZipper String -> Zipper.TextZipper String) -> AppEvent ()
+applyCmdlineEdit zipper = do
+ editor <- gets stateCmdlineEditor
+ let editor' = Editor.applyEdit zipper editor
+ modify (\s -> s {stateCmdlineEditor = editor'})
+
openSelectedFile :: AppEvent ()
openSelectedFile = do
AppState {stateFiles, stateCwd} <- get
diff --git a/lib/Daffm/State.hs b/lib/Daffm/State.hs
index 13fb613..3990ac0 100644
--- a/lib/Daffm/State.hs
+++ b/lib/Daffm/State.hs
@@ -9,15 +9,19 @@ import Data.Char (toLower)
import Data.List (findIndex, sortBy)
import qualified Data.Map.Strict as Map
import Data.Maybe (fromMaybe)
+import qualified Data.Text.Zipper.Generic as Zipper
import qualified Data.Vector as Vec
import System.Directory (listDirectory, makeAbsolute, setCurrentDirectory)
import qualified System.PosixCompat as Posix
+mkEditor :: (Zipper.GenericTextZipper a) => a -> Editor.Editor a FocusTarget
+mkEditor = Editor.editor FocusCmdline (Just 1)
+
mkEmptyAppState :: AppState
mkEmptyAppState =
AppState
{ stateFiles = L.list FocusMain (Vec.fromList []) 1,
- stateCmdlineEditor = Editor.editor FocusCmdline (Just 1) "",
+ stateCmdlineEditor = mkEditor "",
stateFocusTarget = FocusMain,
stateListPositionCache = Map.empty,
stateCwd = "",
@@ -60,6 +64,7 @@ getFileInfo name = do
{ filePath = path,
fileName = name,
fileSize = Posix.fileSize stat,
+ fileMode = Posix.fileMode stat,
fileType = fileTypeFromStatus stat
}
diff --git a/lib/Daffm/Types.hs b/lib/Daffm/Types.hs
index fa9796a..14444f4 100644
--- a/lib/Daffm/Types.hs
+++ b/lib/Daffm/Types.hs
@@ -4,7 +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 System.Posix.Types (FileOffset)
+import System.Posix.Types (FileMode, FileOffset)
data FileType
= RegularFile
@@ -21,6 +21,7 @@ data FileInfo = FileInfo
{ fileName :: String,
filePath :: FilePath,
fileSize :: FileOffset,
+ fileMode :: FileMode,
fileType :: FileType
}
deriving (Show)
@@ -29,7 +30,7 @@ data FocusTarget = FocusCmdline | FocusMain deriving (Show, Eq, Ord)
data AppState = AppState
{ stateFiles :: L.List FocusTarget FileInfo,
- stateCmdlineEditor :: Editor.Editor String FocusTarget,
+ stateCmdlineEditor :: CmdlineEditor,
stateFocusTarget :: FocusTarget,
stateCwd :: FilePath,
stateListPositionCache :: Map.Map String Int,
@@ -38,3 +39,5 @@ data AppState = AppState
deriving (Show)
type AppEvent = EventM FocusTarget AppState
+
+type CmdlineEditor = Editor.Editor String FocusTarget
diff --git a/lib/Daffm/View.hs b/lib/Daffm/View.hs
index 2bfb7dc..3066c93 100644
--- a/lib/Daffm/View.hs
+++ b/lib/Daffm/View.hs
@@ -11,22 +11,23 @@ import qualified Data.Vector as Vec
import Text.Printf (printf)
appView :: AppState -> [Widget FocusTarget]
-appView appState@(AppState {stateFiles, stateCwd}) = [ui]
+appView appState@(AppState {stateFiles}) = [ui]
where
- ui :: Widget FocusTarget
ui = vBox [vLimit 1 header, box, vLimit 1 cmdline]
- header = str stateCwd
+ header = headerView appState
cmdline = cmdlineView appState
- box :: Widget FocusTarget
box = L.renderList fileItemView True stateFiles
hFixed :: Int -> Widget n -> Widget n
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}) =
hBox
- [ hFixed 5 (fileTypeView fileType),
+ [ hFixed 6 (fileTypeView fileType),
hFixed 7 (fileSizeView fileSize),
fileNameView sel fileInfo
]