aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--daffm.cabal1
-rw-r--r--lib/Daffm/Event.hs43
-rw-r--r--lib/Daffm/State.hs2
-rw-r--r--notes.org11
4 files changed, 49 insertions, 8 deletions
diff --git a/daffm.cabal b/daffm.cabal
index 75a49fe..781e01a 100644
--- a/daffm.cabal
+++ b/daffm.cabal
@@ -34,6 +34,7 @@ common common-config
unix-compat <= 0.7.4.1,
mtl == 2.3.1,
containers <= 0.8,
+ text-zipper <= 0.13,
temporary,
text,
vector,
diff --git a/lib/Daffm/Event.hs b/lib/Daffm/Event.hs
index f14ebd8..b9e7398 100644
--- a/lib/Daffm/Event.hs
+++ b/lib/Daffm/Event.hs
@@ -8,10 +8,15 @@ import qualified Brick.Widgets.List as L
import Control.Monad.State (MonadIO (liftIO), MonadState, get, gets, modify, put)
import Daffm.State (cacheDirPosition, loadDirInAppState)
import Daffm.Types (AppState (..), FileInfo (..), FileType (..), FocusTarget (FocusCmdline, FocusMain))
+import Data.Char (isSpace)
+import Data.List (dropWhileEnd)
+import Data.Maybe (fromMaybe)
+import qualified Data.Text as Text
+import qualified Data.Text.Zipper as Z
import Data.Vector ((!?))
import qualified Graphics.Vty as V
import System.FilePath (takeDirectory)
-import System.Process (callProcess)
+import System.Process (callCommand, callProcess)
type AppEvent = T.EventM FocusTarget AppState
@@ -22,17 +27,24 @@ appEvent :: T.BrickEvent FocusTarget e -> AppEvent ()
appEvent brickevent@(T.VtyEvent event) = do
focusTarget <- gets stateFocusTarget
case (focusTarget, event) of
- (FocusCmdline, V.EvKey V.KEsc []) -> modify (\st -> st {stateFocusTarget = FocusMain})
- (FocusMain, V.EvKey (V.KChar ':') []) -> modify (\st -> st {stateFocusTarget = FocusCmdline})
- (FocusMain, V.EvKey (V.KChar 'q') []) -> M.halt
(FocusMain, V.EvKey (V.KChar 'l') []) -> openSelectedFile
(FocusMain, V.EvKey (V.KChar 'h') []) -> goBackToParentDir
(FocusMain, V.EvKey V.KEnter []) -> openSelectedFile
(FocusMain, V.EvKey V.KBS []) -> goBackToParentDir
+ (FocusMain, V.EvKey (V.KChar ':') []) -> modify (\st -> st {stateFocusTarget = FocusCmdline})
+ (FocusMain, V.EvKey (V.KChar 'q') []) -> M.halt
+ (FocusMain, V.EvKey (V.KChar 'r') [V.MCtrl]) -> reloadDir
(FocusMain, _) -> do
files <- gets stateFiles
newFiles <- T.nestEventM' files (L.handleListEventVi L.handleListEvent event)
modify (\appState -> appState {stateFiles = newFiles})
+ (FocusCmdline, V.EvKey V.KEsc []) -> modify (\st -> st {stateFocusTarget = FocusMain})
+ (FocusCmdline, V.EvKey V.KEnter []) -> do
+ gets (trimCmd . Editor.getEditContents . stateCmdlineEditor) >>= evaluateCommand
+ clearEditor
+ modify (\st -> st {stateFocusTarget = FocusMain})
+ where
+ trimCmd = dropWhile isSpace . dropWhileEnd isSpace . unlines
(FocusCmdline, _) -> do
editor <- gets stateCmdlineEditor
newEditor <- T.nestEventM' editor (Editor.handleEditorEvent brickevent)
@@ -40,6 +52,29 @@ appEvent brickevent@(T.VtyEvent event) = do
modify cacheDirPosition
appEvent _ = pure ()
+cmdSubstitutions :: Text.Text -> AppEvent Text.Text
+cmdSubstitutions cmd = do
+ file <- gets (maybe "" (filePath . snd) . L.listSelectedElement . stateFiles)
+ pure $ Text.replace "%" (Text.pack file) cmd
+
+evaluateCommand :: String -> AppEvent ()
+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)
+
openSelectedFile :: AppEvent ()
openSelectedFile = do
AppState {stateFiles, stateCwd} <- get
diff --git a/lib/Daffm/State.hs b/lib/Daffm/State.hs
index cfa9aeb..13fb613 100644
--- a/lib/Daffm/State.hs
+++ b/lib/Daffm/State.hs
@@ -17,7 +17,7 @@ mkEmptyAppState :: AppState
mkEmptyAppState =
AppState
{ stateFiles = L.list FocusMain (Vec.fromList []) 1,
- stateCmdlineEditor = Editor.editor FocusCmdline Nothing "",
+ stateCmdlineEditor = Editor.editor FocusCmdline (Just 1) "",
stateFocusTarget = FocusMain,
stateListPositionCache = Map.empty,
stateCwd = "",
diff --git a/notes.org b/notes.org
index d7f41a0..f504656 100644
--- a/notes.org
+++ b/notes.org
@@ -1,18 +1,23 @@
** Current
- [X] Preserve cursor position per dir while navigating
-- [ ] Cmdline must be single line
+- [X] Cmdline must be single line
+- [X] Reload
- [ ] Commands
-- [ ] Run shell command
-- [ ] Command substitutions (%:filehighlighted %d:cwd %s:selections)
+- [X] Run shell command
+- [X] Command substitution %
+- [ ] Command substitution %d:cwd
- [ ] Show file permissions
** Later
- [ ] handle on open (for external integrations)
- [ ] Cmdline history
- [ ] bind command: define keybindings
- [ ] select multiple files
+- [ ] Command substitution %s:selections
+- [ ] cd into dir symlinks
- [ ] copy/paste across instances
- user-land solution (write selections to file and read from second instance)
- socket
- [ ] support multikey bindings?
- [ ] configuration file (toml?)
- [ ] watch for changes
+- [ ] cmdline tab completion