Skip to content

Commit a71ceea

Browse files
NoFieldSelectors
1 parent aec1cad commit a71ceea

8 files changed

Lines changed: 78 additions & 78 deletions

File tree

Base.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ whenJust = flip $ maybe $ pure ()
5151
xs !? n = listToMaybe $ drop n xs
5252

5353
-- | Zipper structure, representing a list with a cursor.
54-
data Zipper a = Zipper { zipperCur :: !a, zipperBack :: ![a], zipperFront :: ![a] }
54+
data Zipper a = Zipper { cur :: !a, back :: ![a], front :: ![a] }
5555

5656
zipEdit :: (a -> a) -> Zipper a -> Zipper a
57-
zipEdit f z = z { zipperCur = f (zipperCur z) }
57+
zipEdit f z = z { cur = f z.cur }
5858

5959
zipUp, zipDown :: Zipper a -> Zipper a
6060
zipUp (Zipper c (nx:rest) f) = Zipper nx rest (c:f)

Core.hs

Lines changed: 45 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,20 @@ import System.Directory (doesFileExist, findExecutable, createDirectoryI
4444
import System.IO (hPutStrLn, stderr)
4545
import System.Process (runInteractiveProcess, waitForProcess)
4646
import System.Random (randomR, newStdGen)
47-
import System.FilePath ((</>))
48-
import System.Posix.FilePath (takeFileName)
47+
import System.FilePath qualified as FP ((</>))
48+
import System.Posix.FilePath (takeFileName, (</>))
4949
import System.Posix.Process (exitImmediately)
5050

5151

5252
------------------------------------------------------------------------
5353

5454
-- | Command-line configuration.
5555
data Options = Options
56-
{ optPaused :: !Bool -- ^ start in a paused state
57-
, optConfigPath :: !(Maybe FilePath) -- ^ override the style.conf location
58-
, optPlayMode :: Maybe Mode -- ^ play mode
59-
, optHistSize :: Int -- ^ history size
60-
, optRandom :: Bool -- ^ start on random song
56+
{ paused :: !Bool -- ^ start in a paused state
57+
, configPath :: !(Maybe FilePath) -- ^ override the style.conf location
58+
, playMode :: Maybe Mode -- ^ play mode
59+
, histSize :: Int -- ^ history size
60+
, random :: Bool -- ^ start on random song
6161
}
6262

6363
-- | Sets up state, spawns sub-threads, and starts player.
@@ -66,16 +66,16 @@ start opts (Playlist folders music) = do
6666

6767
uiStyle <- UI.start
6868
bootTime <- getMonoTime
69-
mode <- maybe readState pure (optPlayMode opts)
69+
mode <- maybe readState pure opts.playMode
7070
gen <- newStdGen
71-
let (current, randomGen) = if mode == Random || optRandom opts
71+
let (current, randomGen) = if mode == Random || opts.random
7272
then randomR (0, length music - 1) gen else (0, gen)
7373

7474
putMVar hState HState
7575
{ music
7676
, folders
7777
, bootTime
78-
, configPath = optConfigPath opts
78+
, configPath = opts.configPath
7979
, current
8080
, cursor = current
8181
, randomGen
@@ -89,7 +89,7 @@ start opts (Playlist folders music) = do
8989
, playHist = mempty
9090
, searchHist = []
9191
, searchFw = True
92-
, histSize = optHistSize opts
92+
, histSize = opts.histSize
9393
, miniFocused = False
9494
, status = Stopped
9595
, minibuffer = Fast mempty defaultSty
@@ -113,7 +113,7 @@ start opts (Playlist folders music) = do
113113
if ready
114114
then do
115115
playCur
116-
when (optPaused opts) pause -- TODO use LOADPAUSED?
116+
when opts.paused pause -- TODO use LOADPAUSED?
117117
else do
118118
threadDelay 20_000
119119
go (n-1)
@@ -158,10 +158,10 @@ mpgLoop = runForever do
158158
Left err -> do
159159
warnA err
160160
-- Hackily count failed initial spawn, for Ready message
161-
silentlyModifyHS \st -> st { spawns = spawns st `max` 1 }
161+
silentlyModifyHS \st -> st { spawns = st.spawns `max` 1 }
162162
threadDelay 20_000_000 -- longer wait after these errors
163163
Right handles -> do
164-
ct <- modifyHS $ \st -> let sp = spawns st + 1 in (st
164+
ct <- modifyHS $ \st -> let sp = st.spawns + 1 in (st
165165
{ status = Stopped
166166
, info = Nothing
167167
, id3 = Nothing
@@ -186,7 +186,7 @@ refreshLoop = runForever $ takeMVar modified *> UI.refresh
186186
uptimeLoop :: IO ()
187187
uptimeLoop = runForever do
188188
now <- getMonoTime
189-
μs <- modifyHS \st -> let diff = now - bootTime st in
189+
μs <- modifyHS \st -> let diff = now - st.bootTime in
190190
(st { uptime = El.showDuration False diff }, diff `div` 1000)
191191
threadDelay $ fromIntegral $ let m = 60_000_000 in m - μs `mod` m
192192

@@ -226,7 +226,7 @@ handleMsg (I id3) = modifyHS_ $ \st -> st { id3 = Just id3 }
226226
handleMsg (P t) = do
227227
modifyHS_ \st -> st
228228
{ status = t
229-
, clock = case clock st of
229+
, clock = case st.clock of
230230
Just f@Frame{ timeLeft } | t == Stopped && timeLeft < 0.1
231231
-> Just f { timeLeft = 0 } -- force clock to end if near
232232
c -> c
@@ -241,27 +241,27 @@ handleMsg (F f) = do
241241

242242
-- | Seek backward in song
243243
seekLeft :: IO ()
244-
seekLeft = seek \g -> max 0 (currentFrame g - 400)
244+
seekLeft = seek \g -> max 0 (g.currentFrame - 400)
245245

246246
-- | Seek forward in song
247247
seekRight :: IO ()
248-
seekRight = seek \g -> currentFrame g + min 400 (framesLeft g)
248+
seekRight = seek \g -> g.currentFrame + min 400 g.framesLeft
249249

250250
seekStart :: IO ()
251251
seekStart = seek $ const 0
252252

253253
-- | Generic seek
254254
seek :: (Frame -> Int) -> IO ()
255255
seek fn = do
256-
mfr <- getsHS clock
256+
mfr <- getsHS (.clock)
257257
whenJust mfr \fr -> sendMpg $ Jump $ fn fr
258258

259259
------------------------------------------------------------------------
260260

261261
-- | Generic jump
262262
jumpFn :: (Int -> Int) -> IO ()
263263
jumpFn fn = modifyHS_ \st ->
264-
st { cursor = (fn (cursor st) `min` (st.size - 1)) `max` 0 }
264+
st { cursor = (fn st.cursor `min` (st.size - 1)) `max` 0 }
265265

266266
-- | Move cursor up or down
267267
upOne, downOne :: IO ()
@@ -292,8 +292,8 @@ blacklist :: IO ()
292292
blacklist = do
293293
st <- getsHS id
294294
appendFile ".hmp3-delete" . (++"\n") . P.unpack $
295-
let fe = music st ! cursor st
296-
in P.intercalate (P.singleton '/') [dname $ folders st ! fdir fe, fbase fe]
295+
let fe = st.music ! st.cursor
296+
in (st.folders ! fe.fdir).dname </> fe.fbase
297297

298298
------------------------------------------------------------------------
299299

@@ -308,7 +308,7 @@ playCursor = runPlayOp do
308308

309309
-- | Play the song under the cursor (from the start)
310310
playCur :: IO ()
311-
playCur = runPlayOp $ Just <$> gets cursor
311+
playCur = runPlayOp $ Just <$> gets (.cursor)
312312

313313
-- | Play the song before the current song, if we're not at the beginning
314314
-- If we're at the beginning, and loop mode is on, then loop to the end
@@ -371,8 +371,7 @@ runPlayOp op = do
371371
forM mnew \new -> do
372372
HState { .. } <- get
373373
let fe = music ! new
374-
f = P.intercalate (P.singleton '/')
375-
[dname $ folders ! fdir fe, fbase fe]
374+
f = (folders ! fe.fdir).dname </> fe.fbase
376375
modify' \st -> st
377376
{ current = new
378377
, status = Playing
@@ -393,14 +392,14 @@ pause = sendMpg Pause
393392
-- | Always pause
394393
forcePause :: IO ()
395394
forcePause = do
396-
st <- getsHS status
395+
st <- getsHS (.status)
397396
when (st == Playing) pause
398397

399398
------------------------------------------------------------------------
400399

401400
-- | Move cursor to currently playing song
402401
jumpToPlaying :: IO ()
403-
jumpToPlaying = modifyHS_ $ \st -> st { cursor = current st }
402+
jumpToPlaying = modifyHS_ $ \st -> st { cursor = st.current }
404403

405404
-- | Move cursor to first song in next directory (or wrap)
406405
jumpToNextDir, jumpToPrevDir :: IO ()
@@ -410,17 +409,17 @@ jumpToPrevDir = jumpToDir (\i _ -> max (i-1) 0)
410409
-- | Generic jump to dir
411410
jumpToDir :: (Int -> Int -> Int) -> IO ()
412411
jumpToDir fn = modifyHS_ \st ->
413-
let i = fdir (music st ! cursor st)
414-
d = fn i (length $ folders st)
415-
in st { cursor = dlo (folders st ! d) }
412+
let i = (st.music ! st.cursor).fdir
413+
d = fn i (length st.folders)
414+
in st { cursor = (st.folders ! d).dlo }
416415

417416
------------------------------------------------------------------------
418417

419418
-- a bit of bounded parametric polymorphism so we can abstract over record selectors
420419
-- in the regex search stuff below
421420
class Lookup a where extract :: a -> RawFilePath
422-
instance Lookup Dir where extract = takeFileName . dname
423-
instance Lookup File where extract = fbase
421+
instance Lookup Dir where extract = takeFileName . (.dname)
422+
instance Lookup File where extract = (.fbase)
424423

425424
jumpToMatchFile :: Maybe ByteString -> Bool -> IO ()
426425
jumpToMatchFile re sw = genericJumpToMatch re sw k sel
@@ -429,8 +428,8 @@ jumpToMatchFile re sw = genericJumpToMatch re sw k sel
429428

430429
jumpToMatchDir :: Maybe ByteString -> Bool -> IO ()
431430
jumpToMatchDir re sw = genericJumpToMatch re sw k sel
432-
where k st = (folders st, fdir (music st ! cursor st), length $ folders st)
433-
sel i st = dlo (folders st ! i)
431+
where k st = (st.folders, (st.music ! st.cursor).fdir, length st.folders)
432+
sel i st = (st.folders ! i).dlo
434433

435434
genericJumpToMatch :: Lookup a
436435
=> Maybe ByteString
@@ -442,7 +441,7 @@ genericJumpToMatch re sw k sel = do
442441
found <- modifyHS \st -> let
443442
info = case re of
444443
Just s -> Just (st { searchFw = sw }, s, sw)
445-
_ -> listToMaybe [ (st, s, searchFw st == sw) | s <- searchHist st ]
444+
_ -> listToMaybe [ (st, s, st.searchFw == sw) | s <- st.searchHist ]
446445
in flip (maybe (st, False)) info \(st', p, forwards) -> do
447446
let (fs, cur, m) = k st
448447
l = if forwards then [cur+1 .. m-1] ++ [0 .. cur]
@@ -468,16 +467,16 @@ showHist :: IO ()
468467
showHist = do
469468
now <- getMonoTime
470469
setsModal \st -> Just $ HistModal [
471-
(El.showDuration True (now - tm), (ix, fbase $ music st ! ix))
472-
| (tm, ix) <- toList $ playHist st ]
470+
(El.showDuration True (now - tm), (ix, (st.music ! ix).fbase))
471+
| (tm, ix) <- toList st.playHist ]
473472

474473
-- | Focus the minibuffer
475474
toggleFocus :: IO ()
476-
toggleFocus = modifyHS_ $ \st -> st { miniFocused = not (miniFocused st) }
475+
toggleFocus = modifyHS_ $ \st -> st { miniFocused = not st.miniFocused }
477476

478477
-- | Toggle the mode flag
479478
nextMode :: IO ()
480-
nextMode = modifyHS_ $ \st -> st { mode = next (mode st) } where
479+
nextMode = modifyHS_ $ \st -> st { mode = next st.mode } where
481480
next v = if v == maxBound then minBound else succ v
482481

483482
------------------------------------------------------------------------
@@ -490,14 +489,14 @@ writeState :: IO ()
490489
writeState = do
491490
dir <- getStatePath
492491
createDirectoryIfMissing True dir
493-
mode <- getsHS mode
494-
writeFile (dir </> "mode") $ show mode ++ "\n"
492+
mode <- getsHS (.mode)
493+
writeFile (dir FP.</> "mode") $ show mode ++ "\n"
495494

496495
-- | Read mode state
497496
readState :: IO Mode
498497
readState = do
499498
dir <- getStatePath
500-
let f = dir </> "mode"
499+
let f = dir FP.</> "mode"
501500
b <- doesFileExist f
502501
modeM <- if b
503502
then readMaybe <$!> readFile f
@@ -509,11 +508,11 @@ readState = do
509508
--
510509

511510
getConfPath :: IO FilePath
512-
getConfPath = getXdgDirectory XdgConfig $ "hmp3" </> "style.conf"
511+
getConfPath = getXdgDirectory XdgConfig $ "hmp3" FP.</> "style.conf"
513512

514513
loadConfig :: IO ()
515514
loadConfig = do
516-
f <- maybe getConfPath pure =<< getsHS configPath
515+
f <- maybe getConfPath pure =<< getsHS (.configPath)
517516
b <- doesFileExist f
518517
if b then do
519518
str' <- readFile f
@@ -545,6 +544,6 @@ clearMessage = putMessage $ Fast P.empty defaultSty
545544

546545
warnA :: String -> IO ()
547546
warnA x = do
548-
sty <- getsHS uiStyle
549-
putMessage $ Fast (P.pack x) (warnings sty)
547+
sty <- getsHS (.uiStyle.warnings)
548+
putMessage $ Fast (P.pack x) sty
550549

Decoder.hs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ data Msg = I !Id3
4040

4141
-- ID3 info
4242
data Id3 = Id3
43-
{ id3title :: !ByteString
44-
, id3artist :: !ByteString
45-
, id3album :: !ByteString
46-
, id3str :: !ByteString
43+
{ title :: !ByteString
44+
, artist :: !ByteString
45+
, album :: !ByteString
46+
, str :: !ByteString
4747
-- , year :: Maybe ByteString
4848
-- , genre :: Maybe ByteString }
4949
} deriving stock (Eq, Show)
@@ -108,7 +108,7 @@ doI :: ByteString -> Maybe Msg
108108
doI s = I <$> do
109109
("ID3:", info) <- pure $ P.splitAt 4 s
110110
let id3 = parseId3 info
111-
guard $ not $ P.null $ id3title id3 -- title sometimes empty
111+
guard $ not $ P.null $ id3.title -- title sometimes empty
112112
pure id3
113113

114114
-- Format: title (30), author (30), album (30), year (4), comment (30), genre

Keymap.hs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ keyLoop = go mainMode where
4646
-- Top-level normal mode
4747

4848
mainMode :: KeyMap
49-
mainMode = KeyMap \c -> getsHS modal >>= \case
49+
mainMode = KeyMap \c -> getsHS (.modal) >>= \case
5050

5151
Just ExitModal
5252
| c `elem` ['y', 'Y', '\^C'] -> shutdown Nothing $> undefined
@@ -59,7 +59,7 @@ mainMode = KeyMap \c -> getsHS modal >>= \case
5959
_ -> if
6060
| c `elem` ['/', '?', '\\', '|'] -> do
6161
toggleFocus
62-
hist <- getsHS searchHist
62+
hist <- getsHS (.searchHist)
6363
searchMode c $ Zipper "" hist []
6464
| c `elem` ['q', '\^C'] ->
6565
forcePause *> setsModal (const $ Just ExitModal) $> mainMode
@@ -99,20 +99,20 @@ searchMode stype = step where
9999
let jumpy = if stype `elem` ['/', '?']
100100
then jumpToMatchFile else jumpToMatchDir
101101
jumpy (Just pat) (stype `elem` ['/', '\\'])
102-
modifyHS_ \st -> st { searchHist = pat : filter (/= pat) (searchHist st) }
102+
modifyHS_ \st -> st { searchHist = pat : filter (/= pat) st.searchHist }
103103
leave
104104

105105
histDelete z = do
106106
let z' = case z of
107107
Zipper _ b (pv:rest) -> Zipper pv b rest
108108
Zipper _ b _ -> Zipper "" b []
109-
modifyHS_ \st -> st { searchHist = filter (/= zipperCur z) (searchHist st) }
109+
modifyHS_ \st -> st { searchHist = filter (/= z.cur) st.searchHist }
110110
step z'
111111

112112
leave = toggleFocus $> mainMode
113113

114114
renderSearch :: Char -> Zipper ByteString -> IO ()
115-
renderSearch prefix z = putMessage $ Fast (prefix `P.cons` zipperCur z) defaultSty
115+
renderSearch prefix z = putMessage $ Fast (prefix `P.cons` z.cur) defaultSty
116116

117117
enter', delete' :: [Char]
118118
enter' = ['\n', '\r']
@@ -169,5 +169,5 @@ keysHelp = [ (keys, desc) | (desc, keys, _) <- keyTable ]
169169

170170
toggleHelp :: IO ()
171171
toggleHelp = setsModal \st ->
172-
if isNothing $ modal st then Just $ HelpModal keysHelp else Nothing
172+
if isNothing st.modal then Just $ HelpModal keysHelp else Nothing
173173

State.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import Base
1111

1212
import Decoder (Status, Frame, Id3, Cmd, cmdToBS, mp3Tool)
1313
import Playlist (FileArray, DirArray)
14-
import Style (StringA(Fast), UIStyle, warnings)
14+
import Style (StringA(Fast), UIStyle(warnings))
1515

1616
import Data.ByteString (hPut)
1717
import GHC.Records
@@ -117,7 +117,7 @@ sendMpg c = do
117117
ok <- sendMpg' c
118118
when (not ok) do
119119
modifyHS_ \st -> st { minibuffer =
120-
Fast (mp3Tool <> " process not running") (warnings $ uiStyle st) }
120+
Fast (mp3Tool <> " process not running") st.uiStyle.warnings }
121121

122122
------------------------------------------------------------------------
123123
-- State accessor functions.

0 commit comments

Comments
 (0)