···11-{pkgs, ...}: {
22- # name = "screenshot";
33- compiler-nix-name = "ghc928"; # Version of GHC to use
44-55- crossPlatforms = p:
66- pkgs.lib.optionals pkgs.stdenv.hostPlatform.isx86_64 ([
77- p.mingwW64
88- # p.ghcjs # TODO GHCJS support for GHC 9.2
99- ]
1010- ++ pkgs.lib.optionals pkgs.stdenv.hostPlatform.isLinux [
1111- p.musl64
1212- ]);
1313-1414- # Tools to include in the development shell
1515- shell.tools.cabal = "latest";
1616- # shell.tools.hlint = "latest";
1717- # shell.tools.haskell-language-server = "latest";
1818-}
-26
pkgs/screenshot/screenshot.cabal
···11-22--- Instructions on how to write this file are in the Cabal
33--- documentation, which can be found here:
44--- http://haskell.org/cabal/release/cabal-latest/doc/users-guide/
55-66-name: screenshot
77-version: 1.0.0.2
88-stability: stable
99-synopsis: Screenshot tool for hyprland environments
1010-cabal-version: >= 1.6
1111-build-type: Simple
1212-1313-flag threaded
1414- default: False
1515-1616-executable screenshot
1717- hs-source-dirs: src
1818- main-is: Screenshot.hs
1919- build-depends: base >= 4.2 && < 5
2020- , process
2121- , filepath
2222- , time
2323- , bytestring
2424-2525- if flag(threaded)
2626- ghc-options: -threaded
-21
pkgs/screenshot/src/CliArgs.hs
···11-{-# LANGUAGE PatternGuards #-}
22-module CliArgs (parseArgs) where
33-44-import Options
55-66--- TODO: make the error messages good
77-parseArg :: Options -> String -> Options
88-parseArg opts "-c"
99- | File _ <- save opts = error "Cannot use both clipboard and file."
1010- | otherwise = opts { save = Clipboard }
1111-parseArg opts "-f"
1212- | save opts == Clipboard = error "Cannot use both clipboard and file."
1313- | otherwise = opts { save = File Nothing }
1414-parseArg opts ('-':'f':'=':path)
1515- | save opts == Clipboard = error "Cannot use both clipboard and file."
1616- | otherwise = opts { save = File (Just path)}
1717-parseArg _ a = error $ "Invalid argument " ++ a
1818-1919-parseArgs :: [String] -> Options
2020-parseArgs =
2121- foldl parseArg defaultOptions
-62
pkgs/screenshot/src/GetDir.hs
···11-{-# LANGUAGE LambdaCase #-}
22-module GetDir where
33-44-import Data.List (isPrefixOf, intercalate)
55-import Data.Maybe (mapMaybe)
66-import System.Environment (lookupEnv)
77-import System.FilePath ((</>))
88-99-xdgConfigHome :: IO (Maybe String)
1010-xdgConfigHome = do
1111- xdgConfigHome <- lookupEnv "XDG_CONFIG_HOME"
1212- case xdgConfigHome of
1313- Just e -> return (Just e)
1414- Nothing -> do
1515- home <- lookupEnv "HOME"
1616- case home of
1717- Just homePath -> return (Just (homePath </> "/.config/"))
1818- Nothing -> return Nothing
1919-2020-xdgDirsFile :: IO (Maybe String)
2121-xdgDirsFile = do
2222- dotConfig <- xdgConfigHome
2323- case dotConfig of
2424- Just dir -> return (Just (dir </> "user-dirs.dirs"))
2525- Nothing -> return Nothing
2626-2727-parseXdgDirs :: String -> [(String, String)]
2828-parseXdgDirs content =
2929- mapMaybe parseLine (lines content)
3030- where
3131- parseLine :: String -> Maybe (String, String)
3232- parseLine line = case break (=='=') line of
3333- (key, '=':value) -> Just (key, removeQuotes value)
3434- _ -> Nothing
3535-3636- removeQuotes :: String -> String
3737- removeQuotes str
3838- | isPrefixOf "\"" str && isPrefixOf "\"" (reverse str) = init (tail str)
3939- | otherwise = str
4040-4141-getPicturesDir :: IO (Maybe String)
4242-getPicturesDir =
4343- xdgDirsFile >>= \case
4444- Just f -> do
4545- cont <- readFile f
4646- let pictures = lookup "XDG_PICTURES_DIR" $ parseXdgDirs cont
4747- in case pictures of
4848- Just dir -> return (Just dir)
4949- Nothing -> assumedPicturesDir
5050- Nothing -> assumedPicturesDir
5151- where
5252- assumedPicturesDir :: IO (Maybe String)
5353- assumedPicturesDir =
5454- lookupEnv "HOME" >>= \case
5555- Just env -> return (Just (env </> "Pictures/"))
5656- Nothing -> return Nothing
5757-5858-dir :: IO (Maybe String)
5959-dir =
6060- getPicturesDir >>= \case
6161- Just dir -> return (Just (dir </> "screenshots/"))
6262- Nothing -> return Nothing