aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay Nair <phenax5@gmail.com>2025-10-05 11:51:37 +0530
committerAkshay Nair <phenax5@gmail.com>2025-10-05 11:51:37 +0530
commit556f890c3bb799dd6bc1e83c5dcff12f25ed5c24 (patch)
treeb80400bfbaf70cc40abca895ffee9f4de90adec9
parentc999d5703d22a7b73394b50029ceede4ef06f09c (diff)
downloaddaffm-556f890c3bb799dd6bc1e83c5dcff12f25ed5c24.tar.gz
daffm-556f890c3bb799dd6bc1e83c5dcff12f25ed5c24.zip
Add ~ substitution for cd paths
-rw-r--r--config.toml8
-rw-r--r--exe/Main.hs4
-rw-r--r--lib/Daffm/Action/Core.hs19
-rw-r--r--lib/Daffm/State.hs49
-rw-r--r--lib/Daffm/Types.hs1
-rw-r--r--notes.org5
6 files changed, 47 insertions, 39 deletions
diff --git a/config.toml b/config.toml
index 5e4f11e..cdd7d94 100644
--- a/config.toml
+++ b/config.toml
@@ -1,7 +1,7 @@
[keymap]
-gdl = "cd /home/imsohexy/Downloads"
-gdc = "cd /home/imsohexy/Documents"
-gp = "cd /home/imsohexy/Pictures"
-gsc = "cd /home/imsohexy/Pictures/screenshots"
+gdl = "cd ~/Downloads"
+gdc = "cd ~/Documents"
+gp = "cd ~/Pictures"
+gsc = "cd ~/Pictures/screenshots"
dd = "!rm -rfi %f"
pi = "!!clear; chafa -f kitty %"
diff --git a/exe/Main.hs b/exe/Main.hs
index d165653..3ac3375 100644
--- a/exe/Main.hs
+++ b/exe/Main.hs
@@ -6,12 +6,10 @@ import qualified Daffm
import Daffm.Configuration (loadConfigFile)
import qualified Data.Text as Text
import System.Directory (getCurrentDirectory)
-import System.FilePath (takeDirectory)
main :: IO ()
main = do
cwd <- getCurrentDirectory
- let parentDir = Text.pack $ takeDirectory cwd
config <- loadConfigFile
- initialState <- Daffm.loadDirToState (Text.pack cwd) parentDir $ Daffm.mkEmptyAppState config
+ initialState <- Daffm.loadDirToState (Text.pack cwd) $ Daffm.mkEmptyAppState config
void $ M.defaultMain Daffm.app initialState
diff --git a/lib/Daffm/Action/Core.hs b/lib/Daffm/Action/Core.hs
index ce04073..fef6b36 100644
--- a/lib/Daffm/Action/Core.hs
+++ b/lib/Daffm/Action/Core.hs
@@ -18,23 +18,23 @@ import System.Process (callProcess)
modifyM :: (MonadState s m) => (s -> m s) -> m ()
modifyM f = get >>= f >>= put
-loadDir :: FilePathText -> FilePathText -> AppEvent ()
-loadDir dir parentDir = do
- modifyM (liftIO . (>>= filterInvalidSelections) . loadDirToState dir parentDir)
+loadDir :: FilePathText -> AppEvent ()
+loadDir dir = do
+ modifyM (liftIO . (>>= filterInvalidSelections) . loadDirToState dir)
reloadDir :: AppEvent ()
reloadDir = do
- AppState {stateCwd, stateParentDir} <- get
- loadDir stateCwd stateParentDir
+ AppState {stateCwd} <- get
+ loadDir stateCwd
goBackToParentDir :: AppEvent ()
goBackToParentDir = do
- dir <- gets stateParentDir
- loadDir dir (Text.pack . takeDirectory $ Text.unpack dir)
+ dir <- gets (Text.pack . takeDirectory . Text.unpack . stateCwd)
+ loadDir dir
changeDir :: FilePathText -> AppEvent ()
changeDir dir = do
- loadDir dir (Text.pack $ takeDirectory $ Text.unpack dir)
+ loadDir dir
goHome :: AppEvent ()
goHome = do
@@ -47,8 +47,7 @@ openSelectedFile = do
Nothing -> pure ()
openFile :: FileInfo -> AppEvent ()
-openFile (FileInfo {filePath, fileType = Directory}) = do
- gets stateCwd >>= loadDir filePath
+openFile (FileInfo {filePath, fileType = Directory}) = loadDir filePath
openFile (FileInfo {filePath, fileType}) = do
suspendAndResume' $ do
putStrLn $ "Opening " <> show fileType <> ": " <> Text.unpack filePath
diff --git a/lib/Daffm/State.hs b/lib/Daffm/State.hs
index 2596f0c..d1964dc 100644
--- a/lib/Daffm/State.hs
+++ b/lib/Daffm/State.hs
@@ -13,7 +13,8 @@ import qualified Data.Text as Text
import qualified Data.Text.Zipper.Generic as Zipper
import qualified Data.Vector as Vec
import qualified Graphics.Vty as K
-import System.Directory (listDirectory, makeAbsolute, setCurrentDirectory)
+import System.Directory (doesDirectoryExist, getHomeDirectory, listDirectory, makeAbsolute, setCurrentDirectory)
+import System.FilePath (joinPath)
import System.PosixCompat (fileExist)
import qualified System.PosixCompat as Posix
@@ -29,7 +30,6 @@ mkEmptyAppState config =
stateListPositionCache = Map.empty,
stateFileSelections = Set.empty,
stateCwd = "",
- stateParentDir = "",
stateKeyMap = defaultKeymaps <> configKeymap config,
stateKeySequence = []
}
@@ -47,31 +47,42 @@ mkEmptyAppState config =
([K.KChar 'v'], CmdToggleSelection),
([K.KChar '\t'], CmdToggleSelection),
([K.KChar 'C'], CmdClearSelection),
- ([K.KChar '~'], CmdChangeDir "/home/imsohexy"),
- ([K.KChar 'g', K.KChar 'h'], CmdChangeDir "/home/imsohexy")
+ ([K.KChar '~'], CmdChangeDir "~"),
+ ([K.KChar 'g', K.KChar 'h'], CmdChangeDir "~")
]
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
+ if Set.member val set then Set.delete val set else Set.insert val set
toggleFileSelection :: FilePathText -> AppState -> AppState
toggleFileSelection path st = st {stateFileSelections = toggleSetItem path $ stateFileSelections st}
-loadDirToState :: FilePathText -> FilePathText -> AppState -> IO AppState
-loadDirToState dir parentDir appState@(AppState {stateCwd, stateListPositionCache}) = do
- setCurrentDirectory $ Text.unpack dir
- files <- listFilesInDir dir
- let prevDirPosM = findIndex ((== stateCwd) . filePath) files
- let cachedPosM = Map.lookup dir stateListPositionCache
- let pos = fromMaybe 0 (cachedPosM <|> prevDirPosM)
- let list = L.listMoveTo pos $ L.list FocusMain (Vec.fromList files) 1
- pure $
- appState
- { stateFiles = list,
- stateCwd = dir,
- stateParentDir = parentDir
- }
+normalizePath :: FilePathText -> IO FilePathText
+normalizePath (Text.null -> True) = normalizePath "~"
+normalizePath "~" = Text.pack <$> getHomeDirectory
+normalizePath (Text.splitAt 2 -> ("~/", rest)) = do
+ home <- normalizePath "~"
+ pure . Text.pack . joinPath $ map Text.unpack [home, rest]
+normalizePath dir = pure dir
+
+loadDirToState :: FilePathText -> AppState -> IO AppState
+loadDirToState dir' appState@(AppState {stateCwd, stateListPositionCache}) = do
+ dir <- normalizePath dir'
+ doesDirectoryExist (Text.unpack dir) >>= \case
+ True -> do
+ setCurrentDirectory $ Text.unpack dir
+ files <- listFilesInDir dir
+ let prevDirPosM = findIndex ((== stateCwd) . filePath) files
+ let cachedPosM = Map.lookup dir stateListPositionCache
+ let pos = fromMaybe 0 (cachedPosM <|> prevDirPosM)
+ let list = L.listMoveTo pos $ L.list FocusMain (Vec.fromList files) 1
+ pure $
+ appState
+ { stateFiles = list,
+ stateCwd = dir
+ }
+ False -> pure appState
fileTypeFromStatus :: Posix.FileStatus -> FileType
fileTypeFromStatus s =
diff --git a/lib/Daffm/Types.hs b/lib/Daffm/Types.hs
index 7264673..ee25e44 100644
--- a/lib/Daffm/Types.hs
+++ b/lib/Daffm/Types.hs
@@ -40,7 +40,6 @@ data AppState = AppState
stateFocusTarget :: FocusTarget,
stateCwd :: FilePathText,
stateListPositionCache :: Map.Map Text.Text Int,
- stateParentDir :: FilePathText,
stateKeySequence :: KeySequence,
stateKeyMap :: Keymap
}
diff --git a/notes.org b/notes.org
index e21b387..82f75b8 100644
--- a/notes.org
+++ b/notes.org
@@ -15,12 +15,12 @@
- [X] parsing key sequence
- [X] configuration file (toml?)
- [X] Error handling
-- [ ] Expand ~ to home in internal commands (cd)
+- [X] Expand ~ to home in internal commands (cd)
- [ ] Cmdline history
- [ ] Cli arg parsing (dir arg)
- [ ] Opener configuration
+- [ ] Show current pending keys in statusline
** Right after
-- [ ] cd into dir symlinks
- [ ] handle on open (for external integrations)
- [ ] copy/paste across instances
- user-land solution (write selections to file and read from second instance)
@@ -29,6 +29,7 @@
- [ ] Allow escaping % in commands
- [ ] Rethink % substituions
- [ ] theme from config
+- [ ] cd into dir symlinks
** Later
- [ ] Cli arg parsing (-c flag for custom config path)
- [ ] cmdline tab completion