Hclip 0.1.0.0 → 1.0.0.0
raw patch · 2 files changed
+47/−18 lines, 2 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ System.Hclip: MiscError :: String -> ClipboardError
+ System.Hclip: MissingCommands :: [String] -> ClipboardError
+ System.Hclip: NoTextualData :: ClipboardError
+ System.Hclip: UnsupportedOS :: String -> ClipboardError
+ System.Hclip: data ClipboardError
+ System.Hclip: instance Eq ClipboardError
+ System.Hclip: instance Error ClipboardError
+ System.Hclip: instance Show ClipboardError
- System.Hclip: getClipboard :: IO (Either String String)
+ System.Hclip: getClipboard :: IO (Either ClipboardError String)
- System.Hclip: modifyClipboard :: (String -> String) -> IO (Either String String)
+ System.Hclip: modifyClipboard :: (String -> String) -> IO (Either ClipboardError String)
- System.Hclip: setClipboard :: String -> IO (Either String String)
+ System.Hclip: setClipboard :: String -> IO (Either ClipboardError String)
Files
- Hclip.cabal +1/−1
- System/Hclip.hs +46/−17
Hclip.cabal view
@@ -10,7 +10,7 @@ -- PVP summary: +-+------- breaking API changes -- | | +----- non-breaking API additions -- | | | +--- code changes with no API change-version: 0.1.0.0+version: 1.0.0.0 -- A short (one-line) description of the package. synopsis: A small cross-platform library for reading and modifying the system clipboard.
System/Hclip.hs view
@@ -19,7 +19,8 @@ module System.Hclip ( getClipboard, setClipboard, - modifyClipboard+ modifyClipboard,+ ClipboardError(..) ) where import System.Process (runInteractiveCommand, readProcessWithExitCode) @@ -42,49 +43,77 @@ #endif --type ErrorWithIO = ErrorT String IO- -- | Clipboard Actions-data Command = GetClipboard | SetClipboard String +data Command = GetClipboard + | SetClipboard String + -- | Supported Operating Systems data Linux = Linux deriving (Show) data Darwin = Darwin deriving (Show) data Windows = Windows deriving (Show) +-- | Error Types+data ClipboardError = UnsupportedOS String+ | NoTextualData+ | MissingCommands [String]+ | MiscError String+ deriving (Eq)++instance Show ClipboardError where+ show (UnsupportedOS os) = "Unsupported Operating System: " ++ os+ show NoTextualData = "Clipboard doesn't contain textual data."+ show (MissingCommands cmds) = "Hclip requires " ++ apps ++ " installed."+ where apps = intercalate " or " cmds+ show (MiscError str) = str++instance Error ClipboardError where+ noMsg = MiscError "Unknown error"+ strMsg = MiscError+++-- | Monad Transformer combining Error and IO+type ErrorWithIO = ErrorT ClipboardError IO++ -- | type class for supported operating systems class SupportedOS a where- clipboard :: a -> Command -> IO (Either String String)+ clipboard :: a -> Command -> IO (Either ClipboardError String) + -- | read clipboard contents-getClipboard :: IO (Either String String)+getClipboard :: IO (Either ClipboardError String) getClipboard = dispatchCommand GetClipboard + -- | set clipboard contents-setClipboard :: String -> IO (Either String String)+setClipboard :: String -> IO (Either ClipboardError String) setClipboard = dispatchCommand . SetClipboard + -- | apply function to clipboard and return the new contents-modifyClipboard :: (String -> String) -> IO (Either String String)-modifyClipboard = flip (liftM . liftM) getClipboard >=> either (return . Left) setClipboard+modifyClipboard :: (String -> String) -> IO (Either ClipboardError String)+modifyClipboard = flip (liftM . liftM) getClipboard >=> either (return . throwError) setClipboard + -- | select the supported operating system-dispatchCommand :: Command -> IO (Either String String)+dispatchCommand :: Command -> IO (Either ClipboardError String) dispatchCommand = case os of "linux" -> clipboard Linux "darwin" -> clipboard Darwin #if defined(mingw32_HOST_OS) || defined(__MINGW32__) "mingw32" -> clipboard Windows #endif- unknownOS -> const $ return . Left $ "Unsupported OS: " ++ unknownOS+ unknownOS -> const $ return . throwError $ UnsupportedOS unknownOS + -- | MAC OS: use pbcopy and pbpaste instance SupportedOS Darwin where clipboard Darwin GetClipboard = runErrorT $ withExternalCommand "pbcopy" GetClipboard clipboard Darwin c@(SetClipboard s) = runErrorT $ withExternalCommand "pbpaste" c + -- | Linux: use xsel or xclip instance SupportedOS Linux where clipboard Linux command = runErrorT $ do@@ -96,6 +125,7 @@ decode "xclip" GetClipboard = "xclip -selection c -o" decode "xclip" (SetClipboard _) = "xclip -selection c" + -- | Windows: use WinAPI #if defined(mingw32_HOST_OS) || defined(__MINGW32__) instance SupportedOS Windows where@@ -106,7 +136,7 @@ then do h <- getClipboardData cF_TEXT bracket (globalLock h) globalUnlock $ liftM Right . peekCAString . castPtr- else return $ Left "Clipboard doesn't contain textual data"+ else return $ throwError NoTextualData clipboard Windows (SetClipboard s) = withCAString s $ \cstr -> do@@ -126,8 +156,8 @@ withExternalCommand :: String -> Command -> ErrorWithIO String withExternalCommand prog command = liftIO $ bracket (runInteractiveCommand prog)- (\(inp,outp,stderr,_) -> mapM_ hClose [inp,outp,stderr])- (\(inp,outp,_,_) -> (action command) (inp, outp))+ (\(inp, outp, stderr, _) -> mapM_ hClose [inp, outp, stderr])+ (\(inp, outp, _, _) -> (action command) (inp, outp)) where action GetClipboard = hGetContents . stdout action (SetClipboard text) = (flip hPutStr text >=> const (return text)) . stdin@@ -139,10 +169,9 @@ chooseFirstCommand :: [String] -> ErrorWithIO String chooseFirstCommand cmds = do results <- liftIO $ mapM whichCommand cmds- maybe (throwError $ "HClip requires " ++ apps ++ " installed.")+ maybe (throwError $ MissingCommands cmds) return (getFirst . mconcat $ map First results)- where apps = intercalate " or " cmds -- | use the which-command to check if cmd is installed