diff options
| -rw-r--r-- | config.toml | 26 | ||||
| -rw-r--r-- | exe/Main.hs | 61 | ||||
| -rw-r--r-- | lib/Daffm/Configuration.hs | 28 | ||||
| -rw-r--r-- | lib/Daffm/State.hs | 3 | ||||
| -rw-r--r-- | lib/Daffm/Types.hs | 3 | ||||
| -rw-r--r-- | notes.org | 6 |
6 files changed, 93 insertions, 34 deletions
diff --git a/config.toml b/config.toml deleted file mode 100644 index 2e58799..0000000 --- a/config.toml +++ /dev/null @@ -1,26 +0,0 @@ -opener = """ -echo "%F" | while IFS= read file; do - case "$(file --mime-type "$file" -bL)" in - image/*) setsid -f sxiv "$file" >/dev/null 2>&1 ;; - video/*|image/gif) setsid -f mpv "$file" >/dev/null 2>&1 ;; - application/pdf) setsid -f zathura "$file" >/dev/null 2>&1 ;; - *) $EDITOR "$file" ;; - esac -done; -""" - -[keymap] -gdl = "cd ~/Downloads" -gdc = "cd ~/Documents" -gp = "cd ~/Pictures" -gsc = "cd ~/Pictures/screenshots" -gdp = "cd ~/dump" -gmnt = "cd /run/media/imsohexy" - -r = "!!echo '%F' | vidir -v -" -md = "cmdline-set !mkdir -p " -mf = "cmdline-set !touch " -dd = "!rm -rfi %f" -sdd = "!sudo rm -rfi %f" - -"<space>p" = "!!clear; chafa -f kitty %" diff --git a/exe/Main.hs b/exe/Main.hs index 3ac3375..2bfe08b 100644 --- a/exe/Main.hs +++ b/exe/Main.hs @@ -1,15 +1,72 @@ module Main where import qualified Brick.Main as M +import Control.Exception (throwIO) import Control.Monad (void) import qualified Daffm import Daffm.Configuration (loadConfigFile) +import Data.Maybe (fromMaybe) import qualified Data.Text as Text import System.Directory (getCurrentDirectory) +import System.Environment (getArgs) + +data Args = Args + { argsCwd :: Maybe Text.Text, + argsConfigFile :: Maybe FilePath, + argsHelp :: Bool + } + deriving (Show) main :: IO () main = do + args <- getArgs >>= parseArgs + evaluate args + +evaluate :: Args -> IO () +evaluate (Args {argsHelp = True}) = + putStrLn helpMenuContents +evaluate (Args {argsCwd, argsConfigFile}) = do cwd <- getCurrentDirectory - config <- loadConfigFile - initialState <- Daffm.loadDirToState (Text.pack cwd) $ Daffm.mkEmptyAppState config + config <- loadConfigFile argsConfigFile + let dir = fromMaybe (Text.pack cwd) argsCwd + initialState <- Daffm.loadDirToState dir $ Daffm.mkEmptyAppState config void $ M.defaultMain Daffm.app initialState + +parseArgs :: [String] -> IO Args +parseArgs rawArgs = case parsedArgs of + Left e -> throwIO $ userError e + Right v -> pure v + where + parsedArgs = parse rawArgs (Args {argsCwd = Nothing, argsConfigFile = Nothing, argsHelp = False}) + parse :: [String] -> Args -> Either String Args + parse [] args = Right args + parse ("-h" : _) args = Right $ args {argsHelp = True} + parse ("--help" : _) args = Right $ args {argsHelp = True} + parse ("-c" : config : rest) args = parse rest $ args {argsConfigFile = Just config} + parse ["-c"] _ = Left "Missing value for -c arg" + parse ("--config" : config : rest) args = parse rest $ args {argsConfigFile = Just config} + parse ["--config"] _ = Left "Missing value for --config arg" + parse (flag@('-' : _) : _) _ = Left $ "Invalid flag " <> flag + parse (dir : rest) args = parse rest $ args {argsCwd = Just $ Text.pack dir} + +helpMenuContents :: String +helpMenuContents = + unlines + [ "daffm - Dumb as-fuck file manager", + "", + "Usage: daffm [options] [dir]", + "", + "Arguments:", + " [dir]", + " Directory to load. Defaults to current working directory", + "", + "Options:", + " -c, --config <CONFIG-PATH>", + " Load toml config from file", + " If path is prefixed with @, will use alternate config", + " Ex: -c @foo will load $XDG_CONFIG_HOME/daffm/config.foo.toml", + " Default: $XDG_CONFIG_HOME/daffm/config.toml", + "", + " -h, --help", + " This help menu" + ] diff --git a/lib/Daffm/Configuration.hs b/lib/Daffm/Configuration.hs index afcca08..494d2a4 100644 --- a/lib/Daffm/Configuration.hs +++ b/lib/Daffm/Configuration.hs @@ -2,6 +2,7 @@ module Daffm.Configuration where 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 @@ -10,12 +11,35 @@ import qualified Data.Map as Map import Data.Maybe (fromMaybe) import qualified Data.Text as Text import qualified Data.Text.IO as Text +import System.Directory (XdgDirectory (XdgConfig), getXdgDirectory) +import System.FilePath (joinPath) import Toml ((.=)) import qualified Toml -loadConfigFile :: IO Configuration -loadConfigFile = Text.readFile "./config.toml" >>= parse +getConfigDir :: IO FilePath +getConfigDir = getXdgDirectory XdgConfig "daffm" + +getDefaultConfigFilePath :: String -> IO FilePath +getDefaultConfigFilePath "" = do + dir <- getConfigDir + pure $ joinPath [dir, "config.toml"] +getDefaultConfigFilePath name = do + dir <- getConfigDir + pure $ joinPath [dir, "config" <> name <> ".toml"] + +resolveConfigPath :: Maybe String -> IO FilePath +resolveConfigPath Nothing = getDefaultConfigFilePath "" +resolveConfigPath (Just ('@' : name)) = getDefaultConfigFilePath name +resolveConfigPath (Just path) = pure path + +loadConfigFile :: Maybe String -> IO Configuration +loadConfigFile pathM = do + resolveConfigPath pathM >>= (IO.try . Text.readFile) >>= foobar where + foobar :: Either IOError Text.Text -> IO Configuration + foobar rawE = case rawE of + Left _ -> pure defaultConfiguration + Right txt -> parse txt parse txt = case parseConfig txt of Left e -> throwIO $ userError $ show e Right c -> pure c diff --git a/lib/Daffm/State.hs b/lib/Daffm/State.hs index 52ac7a0..1ea8bfe 100644 --- a/lib/Daffm/State.hs +++ b/lib/Daffm/State.hs @@ -49,7 +49,8 @@ mkEmptyAppState config = ([K.KChar '\t'], CmdToggleSelection), ([K.KChar 'C'], CmdClearSelection), ([K.KChar '~'], CmdChangeDir "~"), - ([K.KChar 'g', K.KChar 'h'], CmdChangeDir "~") + ([K.KChar 'g', K.KChar 'h'], CmdChangeDir "~"), + ([K.KChar 'g', K.KChar 'c', K.KChar 'f', K.KChar 'g'], CmdChangeDir "~/.config/daffm") ] toggleSetItem :: (Ord a) => a -> Set.Set a -> Set.Set a diff --git a/lib/Daffm/Types.hs b/lib/Daffm/Types.hs index 39ad5a0..d3dcc70 100644 --- a/lib/Daffm/Types.hs +++ b/lib/Daffm/Types.hs @@ -80,3 +80,6 @@ data Configuration = Configuration configTheme :: !(Map.Map Text.Text Text.Text) } deriving (Show) + +defaultConfiguration :: Configuration +defaultConfiguration = Configuration {configKeymap = Map.empty, configOpener = Nothing, configTheme = Map.empty} @@ -20,19 +20,19 @@ - [X] Opener configuration - [ ] Cmdline history - [ ] Cli arg parsing (dir arg) +- [ ] Cli arg parsing (-c flag for custom config path) ** Right after -- [ ] Command: open-external -- [ ] handle on open (for external integrations) - [ ] copy/paste across instances - user-land solution (write selections to file and read from second instance) - socket +- [ ] Command: open-external +- [ ] handle on open (for external integrations) - [ ] Command: pipe (think about this) (pipe selection file names/file contents) - [ ] 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 - [ ] Allow escaping % in commands - [ ] watch for changes |
