Last active
December 14, 2015 12:52
-
-
Save Cutuchiqueno/e9760ac2e922c5e5054f to your computer and use it in GitHub Desktop.
This small program was the first real program I wrote in Haskel. The only reason why I put it here is the possibility to receive feedback about the abundant inconsistencies, unsafeties and not very elegant decisions which the code provide to learn and leave them behind next time
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- This small program was the first real program I wrote in Haskel. The | |
-- only reason why I put it here is the possibility to receive feedback | |
-- about the abundant inconsistencies, unsafeties and not very elegant | |
-- decisions which the code provide to learn and leave them behind next | |
-- time | |
import Options.Applicative | |
import System.Environment | |
import System.Exit | |
import System.Process | |
import Data.List (isInfixOf) | |
import Text.Regex.PCRE | |
-- parser with optparse-applicative | |
data Options = Options | |
{ extDisplay :: Bool | |
, lapDisplay :: Bool } | |
options :: Parser Options | |
options = Options | |
<$> switch | |
( long "external-display" | |
<> short 'e' | |
<> help "turn on the external display connected to the laptop" ) | |
<*> switch | |
( long "local-display" | |
<> short 'l' | |
<> help "turn on the local display of the laptop" ) | |
greet :: Options -> IO () | |
greet (Options True False) = getDisplays >>= setDisplays 'e' | |
greet (Options False True) = getDisplays >>= setDisplays 'l' | |
greet _ = getDisplays >>= setDisplays 'n' | |
main :: IO () | |
main = execParser opts >>= greet | |
where | |
opts = info (helper <*> options) | |
( fullDesc | |
<> progDesc "Switch between local and external displays" | |
<> header "sctl - a small tool to switch between screen set-ups in a quick way" ) | |
-- programm code | |
data Screen = Screen { display :: String | |
, connected :: Bool | |
, active :: Bool | |
} deriving (Show) | |
getDisplays :: IO [Screen] | |
getDisplays = do | |
output <- readProcess "xrandr" [] "" | |
let oLines = lines output | |
let displayStrs = fmap words ((filter (\line -> isInfixOf " connected " line) oLines)) | |
let scrData = fmap (\display -> Screen (display !!0) | |
(display !!1 == "connected") | |
((concat display) =~ "axis\\)\\d{3}" :: Bool)) | |
displayStrs -- parse active with regular expr | |
return scrData | |
setDisplays :: Char -> [Screen] -> IO() | |
setDisplays mode displays | |
| mode == 'l' = displayOn [(head displays)] >> displayOff (tail displays) | |
| mode == 'e' = displayOn (tail displays) >> displayOff [(head displays)] | |
| mode == 'n' = if (length displays) > 1 then displayOn notrunning >> displayOff running else return () | |
where | |
displayOn on = mapM_ (\id -> callProcess "xrandr" ["--output", display id, "--auto"]) on | |
displayOff off = mapM_ (\id -> callProcess "xrandr" ["--output", display id, "--off"]) off | |
running = filter (\dis -> active dis == True) displays | |
notrunning = filter (\dis -> active dis == False) displays |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment