diff options
Diffstat (limited to '')
| -rw-r--r-- | example-config.toml | 44 | ||||
| -rw-r--r-- | lib/Daffm/Action/Commands.hs | 12 | ||||
| -rw-r--r-- | lib/Daffm/Action/Core.hs | 21 | ||||
| -rw-r--r-- | lib/Daffm/State.hs | 37 | ||||
| -rw-r--r-- | notes.org | 1 |
5 files changed, 77 insertions, 38 deletions
diff --git a/example-config.toml b/example-config.toml index 2947c73..93d8ada 100644 --- a/example-config.toml +++ b/example-config.toml @@ -1,10 +1,16 @@ opener = """ -echo "%F" | while IFS= read file; do +echo "$files" | 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" ;; + *) + if isutf8 -q "$file"; then + $EDITOR "$file" + else + setsid -f xdg-open "$file" + fi + ;; esac done; """ @@ -12,15 +18,15 @@ done; [keymap] md = "cmdline-set !mkdir -p " mf = "cmdline-set !touch " -cl = ["cmdline-set !ln -s %f ", "selection-clear"] -rn = ["!!clear; echo '%F' | vidir -v -", "selection-clear"] -dd = "!clear; echo '%F'; rm -rfIv %f" -sdd = "!clear; echo '%F'; sudo rm -rfIv %f" -cc = ["!!clear; echo 'Duplicated %'; cp -r % %.dup", "selection-clear"] +rn = ["""!! clear; echo "$files" | vidir -v -""", "selection-clear"] +dd = """! clear; echo "$files"; rm -rfIv %f""" +sdd = """! clear; echo "$files"; sudo rm -rfIv %f""" +cc = ["""!! clear; echo "Duplicated $cursor"; cp -r "$cursor" "${cursor}.dup" """, "selection-clear"] cp = ["!!cp -irv %s -t %d", "selection-clear"] mv = ["!!mv -iv %s -t %d", "selection-clear"] gdl = "cd ~/Downloads" +gdm = "cd ~/Downloads/music" gdc = "cd ~/Documents" gp = "cd ~/Pictures" gsc = "cd ~/Pictures/screenshots" @@ -30,12 +36,17 @@ gdv = "cd ~/dev/projects" # Clipboard yy = """shell -relpath=$(realpath -s --relative-to="${DAFFM_PATH_RELATIVE_TO:-$PWD}" %) +relpath=$(realpath -s --relative-to="${DAFFM_PATH_RELATIVE_TO:-$PWD}" "$cursor") echo -n "$relpath" | xclip -selection clipboard """ -YY = "!echo -n % | xclip -selection clipboard" +YY = """shell +echo -n "$cursor" | xclip -selection clipboard +""" +yc = """shell +xclip -selection clipboard -t $(file --mime-type % -bL) -i "$cursor" +""" yf = """shell -xclip -selection clipboard -t $(file --mime-type % -bL) -i % +echo "$files" | sed 's|^|file://|' | xclip -selection clipboard -t text/uri-list -i """ # Mark directories @@ -45,17 +56,18 @@ xclip -selection clipboard -t $(file --mime-type % -bL) -i % "m4" = """eval echo "<daffm>map <space>4 cd %d" """ # Alt openers -"<space>du" = "!!dua ." -"\\xz" = "!!unzip %f" -"\\x7" = "!!7z x %f" -"\\xt" = "!!tar xzf %f" -"\\xr" = "!!unrar x %f" +"<space>du" = "!!dua i ." +"\\xz" = """!! unzip "$cursor" """ +"\\x7" = """!! 7z x "$cursor" """ +"\\xt" = """!! tar xzf "$cursor" """ +"\\xr" = """!! unrar x "$cursor" """ +"\\wi" = """!! wine "$cursor" """ "<space>p" = "preview" [commands] preview = """shell! file='%args' -if [ -z "$file" ]; then file=%; fi +if [ -z "$file" ]; then file="$cursor"; fi clear; case "$file" in *.bmp|*.jpg|*.jpeg|*.png|*.xpm|*.webp|*.gif) chafa -f kitty $file ;; diff --git a/lib/Daffm/Action/Commands.hs b/lib/Daffm/Action/Commands.hs index 9a90f93..39534e1 100644 --- a/lib/Daffm/Action/Commands.hs +++ b/lib/Daffm/Action/Commands.hs @@ -21,6 +21,7 @@ import qualified Data.Text as Text import qualified Data.Text.IO as Text import qualified System.Process as Proc import Text.Read (readMaybe) +import System.Environment (getEnvironment) runCmdline :: AppEvent () runCmdline = do @@ -67,14 +68,16 @@ parseCommand cmd = mkCmd . splitCmdArgs $ trimStart cmd ("", _) -> Nothing (cmd', args) -> Just $ CmdCustom cmd' args -readCommandLines :: Text.Text -> IO [Text.Text] -readCommandLines cmd = do +readCommandLines :: Map.Map String String -> Text.Text -> IO [Text.Text] +readCommandLines env cmd = do + cmdEnv <- (++ Map.toList env) <$> getEnvironment Proc.withCreateProcess (Proc.shell $ Text.unpack cmd) { Proc.delegate_ctlc = True, Proc.std_in = Proc.NoStream, Proc.std_out = Proc.CreatePipe, - Proc.std_err = Proc.NoStream + Proc.std_err = Proc.NoStream, + Proc.env = Just cmdEnv } $ \_ stdout _ p -> do _ <- Proc.waitForProcess p @@ -88,7 +91,8 @@ processCommand (CmdShell waitForKey cmd) args = do cmdSubstitutions (argSubst args cmd) >>= suspendAndRunShellCommand waitForKey reloadDir processCommand (CmdCommandShell cmd) args = do - stdout <- cmdSubstitutions (argSubst args cmd) >>= liftIO . readCommandLines + env <- gets geCommandEnvFromState + stdout <- cmdSubstitutions (argSubst args cmd) >>= liftIO . readCommandLines env forM_ stdout runIfCmd reloadDir where diff --git a/lib/Daffm/Action/Core.hs b/lib/Daffm/Action/Core.hs index ba50638..1ff5737 100644 --- a/lib/Daffm/Action/Core.hs +++ b/lib/Daffm/Action/Core.hs @@ -49,7 +49,7 @@ openSelectedFile = do Just (FileInfo {filePath, fileType = Directory}) -> loadDir filePath Just (FileInfo {filePath, fileLinkType = Just Directory}) -> loadDir filePath Just _ -> do - opener <- gets (fromMaybe "echo '%F' | xargs -i xdg-open {}" . stateOpenerScript) + opener <- gets (fromMaybe "echo \"$files\" | xargs -i xdg-open {}" . stateOpenerScript) cmdSubstitutions opener >>= suspendAndRunShellCommand False Nothing -> pure () @@ -74,19 +74,32 @@ cmdSubstitutions cmd = gets (`substitute` cmd) -- When exit code is non-zero, it will print it and prompt for key press regardless of waitForKey suspendAndRunShellCommand :: Bool -> Text.Text -> AppEvent () suspendAndRunShellCommand waitForKey cmd = do + env <- gets geCommandEnvFromState suspendAndResume' $ do - shellCommand (Text.unpack cmd) Map.empty >>= \case + shellCommand (Text.unpack cmd) env >>= \case Proc.ExitFailure code -> do putStrLn $ "Process exited with " <> show code putStrLn "Press any key to continue" >> void getChar _ | waitForKey -> putStrLn "Press any key to continue" >> void getChar _ -> pure () +geCommandEnvFromState :: AppState -> Map.Map String String +geCommandEnvFromState (AppState {stateFileSelections, stateFiles}) = do + Map.fromList + [ ("files", Text.unpack $ Text.dropWhileEnd (== '\n') $ Text.unlines selectionsOrCursor), + ("selections", Text.unpack $ Text.dropWhileEnd (== '\n') $ Text.unlines selections), + ("cursor", Text.unpack cursorFile) + ] + where + cursorFile = maybe "" (filePath . snd) . L.listSelectedElement $ stateFiles + selections = Set.elems stateFileSelections + selectionsOrCursor = if Set.null stateFileSelections then [cursorFile] else selections + shellCommand :: String -> Map.Map String String -> IO Proc.ExitCode shellCommand cmd env = do - currentEnv <- getEnvironment + cmdEnv <- (++ Map.toList env) <$> getEnvironment Proc.withCreateProcess - (Proc.shell cmd) {Proc.delegate_ctlc = True, Proc.env = Just $ currentEnv ++ Map.toList env} + (Proc.shell cmd) {Proc.delegate_ctlc = True, Proc.env = Just cmdEnv} $ \_ _ _ p -> Proc.waitForProcess p currentFile :: AppEvent (Maybe FileInfo) diff --git a/lib/Daffm/State.hs b/lib/Daffm/State.hs index bc91ecb..9b3d81d 100644 --- a/lib/Daffm/State.hs +++ b/lib/Daffm/State.hs @@ -28,21 +28,30 @@ mkEditor = Editor.editor FocusCmdline (Just 1) mkEmptyAppState :: Configuration -> AppState mkEmptyAppState config = - AppState - { stateFiles = L.list FocusMain (Vec.fromList []) 1, - stateMessage = Nothing, - stateCmdlineEditor = mkEditor "", - stateFocusTarget = FocusMain, - stateListPositionHistory = Map.empty, - stateFileSelections = Set.empty, - stateCwd = "", - stateKeyMap = configKeymap config, + applyConfigToState config $ + AppState + { stateFiles = L.list FocusMain (Vec.fromList []) 1, + stateMessage = Nothing, + stateCmdlineEditor = mkEditor "", + stateFocusTarget = FocusMain, + stateListPositionHistory = Map.empty, + stateFileSelections = Set.empty, + stateCwd = "", + stateKeyMap = Map.empty, + stateOpenerScript = Nothing, + stateKeySequence = [], + stateSearchTerm = Nothing, + stateSearchMatches = Vec.empty, + stateCustomCommands = Map.empty, + stateSearchIndex = 0 + } + +applyConfigToState :: Configuration -> AppState -> AppState +applyConfigToState config state = + state + { stateKeyMap = configKeymap config, stateOpenerScript = configOpener config, - stateKeySequence = [], - stateSearchTerm = Nothing, - stateSearchMatches = Vec.empty, - stateCustomCommands = configCommands config, - stateSearchIndex = 0 + stateCustomCommands = configCommands config } toggleSetItem :: (Ord a) => a -> Set.Set a -> Set.Set a @@ -11,6 +11,7 @@ - [ ] escape % in file paths while substituting - [ ] allow updating selection list (:selection-add, :selection-delete) - [ ] cmdline history +- [ ] ignore C-c interrupt in suspended mode ** Later - [ ] cmdline autocompletion - [ ] generalize cd/opener/back? |
