Skip to content

Commit 75a8755

Browse files
Miscellaneous code improvements.
1 parent 1356f6d commit 75a8755

7 files changed

Lines changed: 41 additions & 88 deletions

File tree

Core.hs

Lines changed: 17 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ blacklist = do
406406
jumpToRandom :: HState -> IO HState
407407
jumpToRandom st = do
408408
n' <- randomIO
409-
let n = abs n' `mod` (size st - 1)
409+
let n = abs n' `mod` size st
410410
playAtN st (const n)
411411

412412
-- | Play the song before the current song, if we're not at the beginning
@@ -520,46 +520,22 @@ genericJumpToMatch :: Lookup a
520520
-> IO ()
521521

522522
genericJumpToMatch re sw k sel = do
523-
found <- modifySTM_ $ \st -> do
523+
found <- modifySTM_ $ \st -> pure do
524524
let mre = case re of
525-
-- work out if we have no pattern, a cached pattern, or a new pattern
526-
Nothing -> case regex st of
527-
Nothing -> Nothing
528-
Just (r,d) -> Just (r,d==sw)
529-
Just s -> case compileM (P.pack s) [caseless,utf8] of
530-
Left _ -> Nothing
531-
Right v -> Just (v,sw)
532-
case mre of
533-
Nothing -> pure (st,False) -- no pattern
534-
Just (p,forwards) -> do
535-
536-
let (fs,cur,m) = k st
537-
538-
{-
539-
loop fn inc n
540-
| fn n = pure Nothing
541-
| otherwise = do
542-
let s = extract (fs ! n)
543-
case match p s [] of
544-
Nothing -> loop fn inc $! inc n
545-
-}
546-
547-
check n = let s = extract (fs ! n) in
548-
case match p s [] of
549-
Nothing -> pure Nothing
550-
Just _ -> pure $ Just n
551-
552-
-- mi <- if forwards then loop (>=m) (+1) (cur+1)
553-
-- else loop (<0) (subtract 1) (cur-1)
554-
mi <- fmap msum $ traverse check $
555-
if forwards then [cur+1..m-1] ++ [0..cur]
556-
else [cur-1,cur-2..0] ++ [m-1,m-2..cur]
557-
558-
559-
let st' = st { regex = Just (p,forwards==sw) }
560-
pure case mi of
561-
Nothing -> (st',False)
562-
Just i -> (st' { cursor = sel i st }, True)
525+
Nothing -> case regex st of
526+
Nothing -> Nothing
527+
Just (r, d) -> Just (r, d==sw)
528+
Just s -> case compileM (P.pack s) [caseless, utf8] of
529+
Left _ -> Nothing
530+
Right v -> Just (v, sw)
531+
flip (maybe (st, False)) mre \ (p, forwards) -> do
532+
let (fs, cur, m) = k st
533+
l = if forwards then [cur+1..m-1] ++ [0..cur]
534+
else [cur-1,cur-2..0] ++ [m-1,m-2..cur]
535+
st' = st { regex = Just (p, forwards==sw) }
536+
case [ i | i <- l, isJust $ match p (extract (fs ! i)) [] ] of
537+
i:_ -> (st' { cursor = sel i st }, True)
538+
_ -> (st', False)
563539

564540
unless found $ putmsg (Fast "No match found." defaultSty) *> touchST
565541

@@ -580,6 +556,7 @@ toggleExit = modifyST $ \st -> st { exitVisible = not (exitVisible st) }
580556
-- | History on or off
581557
hideHist :: IO ()
582558
hideHist = modifyST $ \st -> st { histVisible = Nothing }
559+
583560
showHist :: IO ()
584561
showHist = do
585562
now <- getMonoTime

Lexer.hs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,19 @@ import Control.Monad.Trans (lift)
3434

3535
------------------------------------------------------------------------
3636

37-
pSafeHead :: ByteString -> Char
38-
pSafeHead s = if P.null s then ' ' else P.head s
39-
4037
readPS :: ByteString -> Int
4138
readPS = fst . fromJust . P.readInt
4239

4340
doP :: ByteString -> Msg
44-
doP s = S case pSafeHead s of
45-
'0' -> Stopped
46-
'1' -> Paused
47-
'2' -> Playing
48-
-- mpg123 outputs this but then @P 0 causing double Plays
49-
-- (I think old mpg123 didn't do @P 0 so I added this)
50-
-- '3' -> Stopped -- used by mpg123 for end of song
51-
_ -> Playing
52-
-- _ -> error "Invalid Status"
41+
doP s = S case fst <$> P.uncons s of
42+
Just '0' -> Stopped
43+
Just '1' -> Paused
44+
Just '2' -> Playing
45+
-- mpg123 outputs this but then @P 0 causing double Plays
46+
-- (I think old mpg123 didn't do @P 0 so I added this)
47+
-- '3' -> Stopped -- used by mpg123 for end of song
48+
_ -> Playing
49+
-- _ -> error "Invalid Status"
5350

5451
-- Frame decoding status updates (once per frame).
5552
doF :: ByteString -> Msg

Main.hs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import System.IO (hPrint, stderr)
3131
import System.Posix.Signals (installHandler, sigTERM, sigPIPE, sigINT, sigHUP
3232
,sigALRM, sigABRT, Handler(Ignore, Default, Catch))
3333

34+
import qualified Data.ByteString.UTF8 as UTF8
35+
3436
-- ---------------------------------------------------------------------
3537
-- | Set up the signal handlers
3638

@@ -108,7 +110,7 @@ doArgs = loopArgs True where
108110
--
109111
main :: IO ()
110112
main = do
111-
(playNow, files) <- doArgs . map fromString =<< getArgs
113+
(playNow, files) <- doArgs . map UTF8.fromString =<< getArgs
112114
initSignals
113115
start playNow files -- never returns
114116

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ through 9.10) and libraries. This required rewriting or entirely
2424
replacing large sections, mainly low-level optimizations.
2525

2626
* I added support for building with Stack. It can also be installed
27-
from Nix.
27+
with Nix from nixpkgs (`haskellPackages.hmp3-ng`).
2828

2929
* There is a public GitHub issue tracker, and a GitHub action to
3030
continuously test builds.

Tree.hs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import Base hiding (partition)
2929

3030
import FastIO
3131
import qualified Data.ByteString.Char8 as P
32+
import qualified Data.Map.Strict as M
3233

3334
import Data.Array
3435
import System.IO (hPrint, stderr)
@@ -91,15 +92,7 @@ doOrphans = map \f -> (dirnameP f, [basenameP f])
9192

9293
-- | Merge entries with the same root node into a single node
9394
merge :: [(FilePathP, [FilePathP])] -> [(FilePathP, [FilePathP])]
94-
merge [] = []
95-
merge xs =
96-
let xs' = sortBy (\a b -> fst a `compare` fst b) xs
97-
xs''= groupBy (\a b -> fst a == fst b) xs'
98-
in mapMaybe flatten xs''
99-
where
100-
flatten :: [(FilePathP,[FilePathP])] -> Maybe (FilePathP, [FilePathP])
101-
flatten [] = Nothing -- can't happen
102-
flatten (x:ys) = let d = fst x in Just (d, snd x ++ concatMap snd ys)
95+
merge = M.assocs . M.fromListWith (++)
10396

10497
-- | fold builder, for generating Dirs and Files
10598
make :: (Int,Int,[Dir],[File]) -> (FilePathP,[FilePathP]) -> (Int,Int,[Dir],[File])
@@ -127,14 +120,9 @@ expandDir !f = do
127120
let fs = filter onlyMp3s fs'
128121
v = if null fs then Nothing else Just (f,fs)
129122
pure (v,ds)
130-
where
131-
notEdge p = p /= dot && p /= dotdot
132-
validFiles p = notEdge p
133-
onlyMp3s p = mp3 == (P.map toLower . P.drop (P.length p - 3) $ p)
134-
135-
mp3 = "mp3"
136-
dot = "."
137-
dotdot = ".."
123+
where
124+
validFiles = not . P.isPrefixOf "."
125+
onlyMp3s = P.isSuffixOf ".mp3" . P.map toLower
138126

139127
--
140128
-- | Given an the next index into the files array, a directory name, and

UI.hs

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ import Config
5252
import qualified UI.HSCurses.Curses as Curses
5353
import {-# SOURCE #-} Keymap (extraTable, keyTable, unkey, charToKey)
5454

55-
import Data.Array ((!), bounds, Array, listArray)
55+
import Data.Array ((!), bounds, Array)
5656
import Data.Array.Base (unsafeAt)
5757
import System.IO (stderr, hFlush)
5858
import System.Posix.Signals (raiseSignal, sigTSTP, installHandler, Handler(..))
@@ -577,18 +577,8 @@ printPlayList (PlayList s) = s
577577

578578
------------------------------------------------------------------------
579579

580-
-- | Calculate whitespaces, very common, so precompute likely values
581580
spaces :: Int -> ByteString
582-
spaces n
583-
| n <= 0 = ""
584-
| n > 100 = P.replicate n ' ' -- unlikely
585-
| otherwise = arr ! n
586-
where
587-
arr :: Array Int ByteString -- precompute some whitespace strs
588-
arr = listArray (0,100) [ P.take i s100 | i <- [0..100] ]
589-
590-
s100 :: ByteString
591-
s100 = P.replicate 100 ' ' -- seems reasonable
581+
spaces = flip P.replicate ' '
592582

593583
------------------------------------------------------------------------
594584
--
@@ -626,7 +616,6 @@ renderModal st (Size h w) = do
626616
(y',_) <- Curses.getYX Curses.stdScr
627617
Curses.wMove Curses.stdScr (y'+1) hoffset
628618

629-
-- XXX don't understand what sz is even doing
630619
renderModals :: HState -> Size -> IO ()
631620
renderModals s sz = do
632621
renderModal @HelpModal s sz

hmp3-ng.cabal

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
cabal-version: 2.2
1+
cabal-version: 3.0
22

33
name: hmp3-ng
4-
version: 2.17.3
4+
version: 2.18.0
55
synopsis: A 2019 fork of an ncurses mp3 player written in Haskell
66
description: An mp3 player with a curses frontend. Playlists are populated by
77
passing file and directory names on the command line. 'h' displays
@@ -15,8 +15,9 @@ license: GPL-2.0-or-later
1515
license-file: LICENSE
1616
build-type: Simple
1717
extra-source-files:
18-
README.md
1918
Keymap.hs-boot
19+
extra-doc-files:
20+
README.md
2021

2122
source-repository head
2223
type: git
@@ -45,7 +46,6 @@ executable hmp3
4546
default-extensions:
4647
BangPatterns
4748
BlockArguments
48-
NondecreasingIndentation
4949
OverloadedStrings
5050
ScopedTypeVariables
5151
TypeApplications

0 commit comments

Comments
 (0)