aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Daffm/Action/Commands.hs6
-rw-r--r--lib/Daffm/Action/Core.hs4
-rw-r--r--lib/Daffm/Configuration.hs12
-rw-r--r--lib/Daffm/State.hs21
-rw-r--r--lib/Daffm/Types.hs13
-rw-r--r--notes.org8
6 files changed, 40 insertions, 24 deletions
diff --git a/lib/Daffm/Action/Commands.hs b/lib/Daffm/Action/Commands.hs
index a9b706f..a5116eb 100644
--- a/lib/Daffm/Action/Commands.hs
+++ b/lib/Daffm/Action/Commands.hs
@@ -4,13 +4,13 @@
module Daffm.Action.Commands where
import qualified Brick as M
+import Control.Monad (forM_)
import Daffm.Action.Cmdline
import Daffm.Action.Core
import Daffm.Types
import Daffm.Utils (trimStart)
import Data.Bifunctor (Bifunctor (second))
import Data.Char (isSpace)
-import Data.Maybe (fromMaybe)
import qualified Data.Text as Text
runCmdline :: AppEvent ()
@@ -24,8 +24,7 @@ parseCommand (Text.splitAt 2 -> ("!!", cmd)) = Just $ CmdShell True cmd
parseCommand (Text.splitAt 1 -> ("!", cmd)) = Just $ CmdShell False cmd
parseCommand cmd = mkCmd . splitCmdArgs $ trimStart cmd
where
- splitCmdArgs = second trimStart . Text.splitAt cmdEndIdx
- cmdEndIdx = fromMaybe (Text.length cmd) $ Text.findIndex isSpace cmd
+ splitCmdArgs = second trimStart . Text.break isSpace
mkCmd = \case
("q", _) -> Just CmdQuit
("quit", _) -> Just CmdQuit
@@ -57,6 +56,7 @@ processCommand CmdReload = reloadDir
processCommand CmdToggleSelection = toggleCurrentFileSelection
processCommand CmdClearSelection = clearFileSelections
processCommand CmdGoBack = goBackToParentDir
+processCommand (CmdChain chain) = forM_ chain processCommand
processCommand CmdNoop = pure ()
evaluateCommand :: Text.Text -> AppEvent ()
diff --git a/lib/Daffm/Action/Core.hs b/lib/Daffm/Action/Core.hs
index f80e41a..a8dad32 100644
--- a/lib/Daffm/Action/Core.hs
+++ b/lib/Daffm/Action/Core.hs
@@ -65,8 +65,8 @@ cmdSubstitutions cmd = do
let selections = Set.elems stateFileSelections
let selectionsOrCurrent = if Set.null stateFileSelections then [file] else selections
let subst =
- Text.replace "%" file
- . Text.replace "%d" stateCwd
+ Text.replace "%" (escape file)
+ . Text.replace "%d" (escape stateCwd)
. Text.replace "%s" (Text.unwords $ map escape selections)
. Text.replace "%S" (Text.dropWhileEnd (== '\n') $ Text.unlines selections)
. Text.replace "%f" (Text.unwords $ map escape selectionsOrCurrent)
diff --git a/lib/Daffm/Configuration.hs b/lib/Daffm/Configuration.hs
index 494d2a4..d3691cd 100644
--- a/lib/Daffm/Configuration.hs
+++ b/lib/Daffm/Configuration.hs
@@ -1,12 +1,13 @@
module Daffm.Configuration where
+import Control.Applicative ((<|>))
import Control.Arrow (ArrowChoice (left))
import Control.Exception (throwIO)
import qualified Control.Exception as IO
import Daffm.Action.Commands (parseCommand)
import Daffm.Keymap (parseKeySequence)
import Daffm.Types
-import Data.Bifunctor (Bifunctor (bimap))
+import Data.Bifunctor (Bifunctor (first))
import qualified Data.Map as Map
import Data.Maybe (fromMaybe)
import qualified Data.Text as Text
@@ -25,7 +26,7 @@ getDefaultConfigFilePath "" = do
pure $ joinPath [dir, "config.toml"]
getDefaultConfigFilePath name = do
dir <- getConfigDir
- pure $ joinPath [dir, "config" <> name <> ".toml"]
+ pure $ joinPath [dir, "config." <> name <> ".toml"]
resolveConfigPath :: Maybe String -> IO FilePath
resolveConfigPath Nothing = getDefaultConfigFilePath ""
@@ -59,8 +60,11 @@ configurationCodec =
keymapCodec :: Toml.Key -> Toml.TomlCodec Keymap
keymapCodec = Toml.dimap (const Map.empty) toKeymap . keymapRawCodec
where
- keymapRawCodec = Toml.tableMap Toml._KeyText Toml.text
- toKeymap = Map.fromList . map (bimap toKeys toCmd) . Map.toList
+ keymapRawCodec = Toml.tableMap Toml._KeyText commandCodec
+ toKeymap = Map.fromList . map (first toKeys) . Map.toList
toKeys = fromMaybe [] . parseKeySequence . stripQuotes
toCmd = fromMaybe CmdNoop . parseCommand
stripQuotes txt = fromMaybe txt (Text.stripPrefix "\"" txt >>= Text.stripSuffix "\"")
+ commandCodec k = cmdCodec k <|> cmdChainCodec k
+ cmdCodec = Toml.dimap (const "") toCmd . Toml.text
+ cmdChainCodec = Toml.dimap (const []) (CmdChain . map toCmd) . Toml.arrayOf Toml._Text
diff --git a/lib/Daffm/State.hs b/lib/Daffm/State.hs
index fd5818d..355acab 100644
--- a/lib/Daffm/State.hs
+++ b/lib/Daffm/State.hs
@@ -5,6 +5,7 @@ import qualified Brick.Widgets.List as L
import Control.Applicative ((<|>))
import Control.Monad (filterM, forM)
import Daffm.Types
+import Daffm.Utils (trim)
import Data.List (findIndex, sortBy)
import qualified Data.Map.Strict as Map
import Data.Maybe (fromMaybe)
@@ -22,7 +23,7 @@ defaultKeymaps :: Keymap
defaultKeymaps =
Map.fromList
[ ([K.KChar 'q'], CmdQuit),
- ([K.KChar 'r'], CmdReload),
+ ([K.KChar 'r', K.KChar 'r'], CmdReload),
([K.KChar '!'], CmdSetCmdline "!"),
([K.KChar ':'], CmdEnterCmdline),
([K.KChar 'l'], CmdOpenSelection),
@@ -51,7 +52,7 @@ mkEmptyAppState config =
stateListPositionHistory = Map.empty,
stateFileSelections = Set.empty,
stateCwd = "",
- stateKeyMap = defaultKeymaps <> configKeymap config,
+ stateKeyMap = configKeymap config <> defaultKeymaps,
stateOpenerScript = configOpener config,
stateKeySequence = []
}
@@ -64,16 +65,22 @@ toggleFileSelection :: FilePathText -> AppState -> AppState
toggleFileSelection path st = st {stateFileSelections = toggleSetItem path $ stateFileSelections st}
normalizePath :: FilePathText -> IO FilePathText
-normalizePath (Text.null -> True) = normalizePath "~"
+normalizePath (Text.null -> True) = Text.pack <$> getHomeDirectory
normalizePath "~" = Text.pack <$> getHomeDirectory
-normalizePath (Text.splitAt 2 -> ("~/", rest)) = do
- home <- normalizePath "~"
- pure . Text.pack . joinPath $ map Text.unpack [home, rest]
+normalizePath (Text.stripPrefix "~/" -> (Just rest)) = do
+ home <- getHomeDirectory
+ pure . Text.pack . joinPath $ [home, Text.unpack rest]
normalizePath dir = pure dir
+stripQuotes :: Text.Text -> Text.Text
+stripQuotes txt = fromMaybe txt (double <|> single)
+ where
+ double = Text.stripPrefix "\"" txt >>= Text.stripSuffix "\""
+ single = Text.stripPrefix "'" txt >>= Text.stripSuffix "'"
+
loadDirToState :: FilePathText -> AppState -> IO AppState
loadDirToState dir' appState@(AppState {stateCwd, stateListPositionHistory}) = do
- dir <- normalizePath dir'
+ dir <- normalizePath . stripQuotes $ trim dir'
doesDirectoryExist (Text.unpack dir) >>= \case
True -> do
setCurrentDirectory $ Text.unpack dir
diff --git a/lib/Daffm/Types.hs b/lib/Daffm/Types.hs
index d3dcc70..197ab63 100644
--- a/lib/Daffm/Types.hs
+++ b/lib/Daffm/Types.hs
@@ -34,15 +34,15 @@ data FileInfo = FileInfo
data FocusTarget = FocusCmdline | FocusMain deriving (Show, Eq, Ord)
data AppState = AppState
- { stateFiles :: L.List FocusTarget FileInfo,
- stateCmdlineEditor :: CmdlineEditor,
+ { stateCmdlineEditor :: CmdlineEditor,
+ stateCwd :: FilePathText,
stateFileSelections :: Set.Set FilePathText,
+ stateFiles :: L.List FocusTarget FileInfo,
stateFocusTarget :: FocusTarget,
- stateCwd :: FilePathText,
- stateListPositionHistory :: Map.Map Text.Text Int,
+ stateKeyMap :: Keymap,
stateKeySequence :: KeySequence,
- stateOpenerScript :: Maybe Text.Text,
- stateKeyMap :: Keymap
+ stateListPositionHistory :: Map.Map Text.Text Int,
+ stateOpenerScript :: Maybe Text.Text
}
deriving (Show)
@@ -65,6 +65,7 @@ data Command
| CmdToggleSelection
| CmdClearSelection
| CmdGoBack
+ | CmdChain [Command]
| CmdNoop
deriving (Show, Eq)
diff --git a/notes.org b/notes.org
index 88db27c..3bfd14c 100644
--- a/notes.org
+++ b/notes.org
@@ -20,13 +20,17 @@
- [X] Opener configuration
- [X] Cli arg parsing (dir arg)
- [X] Cli arg parsing (-c flag for custom config path)
+- [X] handle on open (for external integrations) (opener in custom config)
+- [X] chain multiple commands
+- [ ] Store last directory path
+- [ ] Store selections path
- [ ] Command: search, search-next, search-prev
** Right after
-- [ ] copy/paste across instances
+- [ ] copy/move/paste selections across instances
- user-land solution (write selections to file and read from second instance)
- socket
+- [ ] think about nvim integration (server + send back)
- [ ] Fix keymap evaluation: If v is bound, it doesnt evaluate vd since v was found
-- [X] handle on open (for external integrations) (opener in custom config)
- [ ] Cmdline history
- [ ] Command: pipe (think about this) (pipe selection file names/file contents)
- [ ] Allow escaping % in commands