-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvolume.hs
72 lines (53 loc) · 2.14 KB
/
volume.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
{-# LANGUAGE OverloadedStrings #-}
{-| Modify or print the volume, using the `amixer` command.
Refreshes tmux if it is displaying the volume.
Creates a notification announcing the new volume using `notify`.
-}
import Data.String (fromString)
import Turtle
data Command = Up Int | Down Int | Toggle | Print deriving (Eq, Show)
type Volume = Text
main = do
command <- options "Modify or print the volume" argsParser
changeVolume command
-- TODO: Handle no output
output <- amixerOutput
volume <- case match signedVolumePattern output of
[left, _] -> pure left
_ -> die "Unable to parse amixer output"
announceVolumeChanges command volume
printVolume command volume
argsParser :: Parser Command
argsParser = Up <$> optInt "up" 'u' "Increase the volume by percentage [1 to 100]"
<|> Down <$> optInt "down" 'd' "Decrease the volume by percentage [1 to 100]"
<|> Print <$ switch "print" 'p' "Print the volume"
<|> Toggle <$ switch "toggle" 't' "Toggle sound mute"
changeVolume :: Command -> IO ()
changeVolume (Up amt) = run ("amixer -q sset Master,0 " <> showS amt <> "%+")
changeVolume (Down amt) = run ("amixer -q sset Master,0 " <> showS amt <> "%-")
changeVolume Toggle = run "amixer -q sset Master,0 toggle"
changeVolume Print = pure ()
announceVolumeChanges :: Command -> Volume -> IO ()
announceVolumeChanges Print _ = pure ()
announceVolumeChanges _ volume = do
-- Update tmux
run "tmux refresh -S"
-- Create desktop notification
run ("notify volume " <> volume)
printVolume :: Command -> Volume -> IO ()
printVolume Print volume = echo volume
printVolume _ _ = pure ()
amixerOutput :: IO Text
amixerOutput = snd <$> procStrict "amixer" ["get", "Master,0"] empty
signedVolumePattern :: Pattern Volume
signedVolumePattern = do
chars
volume <- "[" *> decimal <* "%]"
spaces1
on <- "[" *> ("on" <|> "off") <* "]"
chars
pure (showS volume <> if on == "on" then "+" else "-")
showS :: (Show a, IsString b) => a -> b
showS = fromString . show
run :: Text -> IO ()
run cmd = sh (inshell cmd empty)