From ae37e13986b45150f69d7cfa2555cf6b22ccc3c9 Mon Sep 17 00:00:00 2001 From: Olivier Schneider Date: Sat, 3 Mar 2018 15:50:02 +0100 Subject: Add ellipsis option for Monitor's fields and total text --- .gitignore | 4 +++ readme.md | 10 ++++++ src/Plugins/Monitors/Common.hs | 66 ++++++++++++++++++++++--------------- src/Plugins/Monitors/Top.hs | 2 +- test/Plugins/Monitors/CommonSpec.hs | 29 ++++++++++++++++ test/Spec.hs | 1 + xmobar.cabal | 42 +++++++++++++++++++++++ 7 files changed, 126 insertions(+), 28 deletions(-) create mode 100644 test/Plugins/Monitors/CommonSpec.hs create mode 100644 test/Spec.hs diff --git a/.gitignore b/.gitignore index e1bb15b..625eb87 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,7 @@ cabal.sandbox.config .stack-work /web/readme.md +/.idea/ +/xmobar.iml +/out/ +/cabal.config diff --git a/readme.md b/readme.md index ae2edf1..116404c 100644 --- a/readme.md +++ b/readme.md @@ -642,6 +642,11 @@ These are the options available for all monitors below: than this value will be truncated. - Long option: `--maxwidth` - Default: 0 (no maximum width) +- `-e` _string_ Maximum width ellipsis + - Ellipsis to be added to the field when it has reached its + max width. + - Long option: `--maxwidthellipsis` + - Default: "" (no ellipsis) - `-w` _number_ Fixed field width - All fields will be set to this width, padding or truncating as needed. @@ -651,6 +656,11 @@ These are the options available for all monitors below: - Maximum total width of the text. - Long option: `--maxtwidth` - Default: 0 (no limit) +- `-E` _string_ Maximum total width ellipsis + - Ellipsis to be added to the total text when it has reached + its max width. + - Long option: `--maxtwidthellipsis` + - Default: "" (no ellipsis) - `-c` _string_ - Characters used for padding. The characters of _string_ are used cyclically. E.g., with `-P +- -w 6`, a field with value "foo" diff --git a/src/Plugins/Monitors/Common.hs b/src/Plugins/Monitors/Common.hs index 55f67d7..91d491e 100644 --- a/src/Plugins/Monitors/Common.hs +++ b/src/Plugins/Monitors/Common.hs @@ -93,6 +93,7 @@ data MConfig = , decDigits :: IORef Int , minWidth :: IORef Int , maxWidth :: IORef Int + , maxWidthEllipsis :: IORef String , padChars :: IORef String , padRight :: IORef Bool , barBack :: IORef String @@ -101,6 +102,7 @@ data MConfig = , useSuffix :: IORef Bool , naString :: IORef String , maxTotalWidth :: IORef Int + , maxTotalWidthEllipsis :: IORef String } -- | from 'http:\/\/www.haskell.org\/hawiki\/MonadState' @@ -138,6 +140,7 @@ mkMConfig tmpl exprts = d <- newIORef 0 mn <- newIORef 0 mx <- newIORef 0 + mel <- newIORef "" pc <- newIORef " " pr <- newIORef False bb <- newIORef ":" @@ -146,7 +149,8 @@ mkMConfig tmpl exprts = up <- newIORef False na <- newIORef "N/A" mt <- newIORef 0 - return $ MC nc l lc h hc t e p d mn mx pc pr bb bf bw up na mt + mtel <- newIORef "" + return $ MC nc l lc h hc t e p d mn mx mel pc pr bb bf bw up na mt mtel data Opts = HighColor String | NormalColor String @@ -159,6 +163,7 @@ data Opts = HighColor String | MinWidth String | MaxWidth String | Width String + | WidthEllipsis String | PadChars String | PadAlign String | BarBack String @@ -167,6 +172,7 @@ data Opts = HighColor String | UseSuffix String | NAString String | MaxTotalWidth String + | MaxTotalWidthEllipsis String options :: [OptDescr Opts] options = @@ -183,6 +189,7 @@ options = , Option "m" ["minwidth"] (ReqArg MinWidth "minimum width") "Minimum field width" , Option "M" ["maxwidth"] (ReqArg MaxWidth "maximum width") "Maximum field width" , Option "w" ["width"] (ReqArg Width "fixed width") "Fixed field width" + , Option "e" ["maxwidthellipsis"] (ReqArg WidthEllipsis "Maximum width ellipsis") "Ellipsis to be added to the field when it has reached its max width." , Option "c" ["padchars"] (ReqArg PadChars "padding chars") "Characters to use for padding" , Option "a" ["align"] (ReqArg PadAlign "padding alignment") "'l' for left padding, 'r' for right" , Option "b" ["bback"] (ReqArg BarBack "bar background") "Characters used to draw bar backgrounds" @@ -190,6 +197,7 @@ options = , Option "W" ["bwidth"] (ReqArg BarWidth "bar width") "Bar width" , Option "x" ["nastring"] (ReqArg NAString "N/A string") "String used when the monitor is not available" , Option "T" ["maxtwidth"] (ReqArg MaxTotalWidth "Maximum total width") "Maximum total width" + , Option "E" ["maxtwidthellipsis"] (ReqArg MaxTotalWidthEllipsis "Maximum total width ellipsis") "Ellipsis to be added to the total text when it has reached its max width." ] doArgs :: [String] -> ([String] -> Monitor String) -> ([String] -> Monitor Bool) -> Monitor String @@ -209,26 +217,28 @@ doConfigOptions (o:oo) = nz s = let x = read s in max 0 x bool = (`elem` ["True", "true", "Yes", "yes", "On", "on"]) (case o of - High h -> setConfigValue (read h) high - Low l -> setConfigValue (read l) low - HighColor c -> setConfigValue (Just c) highColor - NormalColor c -> setConfigValue (Just c) normalColor - LowColor c -> setConfigValue (Just c) lowColor - Template t -> setConfigValue t template - PercentPad p -> setConfigValue (nz p) ppad - DecDigits d -> setConfigValue (nz d) decDigits - MinWidth w -> setConfigValue (nz w) minWidth - MaxWidth w -> setConfigValue (nz w) maxWidth - Width w -> setConfigValue (nz w) minWidth >> - setConfigValue (nz w) maxWidth - PadChars s -> setConfigValue s padChars - PadAlign a -> setConfigValue ("r" `isPrefixOf` a) padRight - BarBack s -> setConfigValue s barBack - BarFore s -> setConfigValue s barFore - BarWidth w -> setConfigValue (nz w) barWidth - UseSuffix u -> setConfigValue (bool u) useSuffix - NAString s -> setConfigValue s naString - MaxTotalWidth w -> setConfigValue (nz w) maxTotalWidth) >> next + High h -> setConfigValue (read h) high + Low l -> setConfigValue (read l) low + HighColor c -> setConfigValue (Just c) highColor + NormalColor c -> setConfigValue (Just c) normalColor + LowColor c -> setConfigValue (Just c) lowColor + Template t -> setConfigValue t template + PercentPad p -> setConfigValue (nz p) ppad + DecDigits d -> setConfigValue (nz d) decDigits + MinWidth w -> setConfigValue (nz w) minWidth + MaxWidth w -> setConfigValue (nz w) maxWidth + Width w -> setConfigValue (nz w) minWidth >> + setConfigValue (nz w) maxWidth + WidthEllipsis e -> setConfigValue e maxWidthEllipsis + PadChars s -> setConfigValue s padChars + PadAlign a -> setConfigValue ("r" `isPrefixOf` a) padRight + BarBack s -> setConfigValue s barBack + BarFore s -> setConfigValue s barFore + BarWidth w -> setConfigValue (nz w) barWidth + UseSuffix u -> setConfigValue (bool u) useSuffix + NAString s -> setConfigValue s naString + MaxTotalWidth w -> setConfigValue (nz w) maxTotalWidth + MaxTotalWidthEllipsis e -> setConfigValue e maxTotalWidthEllipsis) >> next runM :: [String] -> IO MConfig -> ([String] -> Monitor String) -> Int -> (String -> IO ()) -> IO () @@ -336,9 +346,10 @@ parseTemplate l = do t <- getConfigValue template e <- getConfigValue export w <- getConfigValue maxTotalWidth + ellipsis <- getConfigValue maxTotalWidthEllipsis let m = Map.fromList . zip e $ l s <- parseTemplate' t m - return $ if w > 0 && length s > w then take w s else s + return $ if w > 0 && length s > w then take w s ++ ellipsis else s -- | Parses the template given to it with a map of export values and combines -- them @@ -390,15 +401,15 @@ showWithUnits d n x | otherwise = showWithUnits d (n+1) (x/1024) where units = (!!) ["B", "K", "M", "G", "T"] -padString :: Int -> Int -> String -> Bool -> String -> String -padString mnw mxw pad pr s = +padString :: Int -> Int -> String -> Bool -> String -> String -> String +padString mnw mxw pad pr ellipsis s = let len = length s rmin = if mnw <= 0 then 1 else mnw rmax = if mxw <= 0 then max len rmin else mxw (rmn, rmx) = if rmin <= rmax then (rmin, rmax) else (rmax, rmin) rlen = min (max rmn len) rmx in if rlen < len then - take rlen s + take rlen s ++ ellipsis else let ps = take (rlen - len) (cycle pad) in if pr then s ++ ps else ps ++ s @@ -420,7 +431,7 @@ floatToPercent n = up <- getConfigValue useSuffix let p = showDigits 0 (n * 100) ps = if up then "%" else "" - return $ padString pad pad pc pr p ++ ps + return $ padString pad pad pc pr "" p ++ ps stringParser :: Pos -> B.ByteString -> String stringParser (x,y) = @@ -442,7 +453,8 @@ showWithPadding s = mx <- getConfigValue maxWidth p <- getConfigValue padChars pr <- getConfigValue padRight - return $ padString mn mx p pr s + ellipsis <- getConfigValue maxWidthEllipsis + return $ padString mn mx p pr ellipsis s colorizeString :: (Num a, Ord a) => a -> String -> Monitor String colorizeString x s = do diff --git a/src/Plugins/Monitors/Top.hs b/src/Plugins/Monitors/Top.hs index 3d246ff..d60897d 100644 --- a/src/Plugins/Monitors/Top.hs +++ b/src/Plugins/Monitors/Top.hs @@ -80,7 +80,7 @@ showInfo nm sms mms = do let lsms = length sms nmw = mnw - lsms - 1 nmx = mxw - lsms - 1 - rnm = if nmw > 0 then padString nmw nmx " " True nm else nm + rnm = if nmw > 0 then padString nmw nmx " " True "" nm else nm mstr <- showWithColors' sms mms both <- showWithColors' (rnm ++ " " ++ sms) mms return [nm, mstr, both] diff --git a/test/Plugins/Monitors/CommonSpec.hs b/test/Plugins/Monitors/CommonSpec.hs new file mode 100644 index 0000000..847368c --- /dev/null +++ b/test/Plugins/Monitors/CommonSpec.hs @@ -0,0 +1,29 @@ +module Plugins.Monitors.CommonSpec + ( main + , spec + ) where + +import Test.Hspec +import Plugins.Monitors.Common + +main :: IO () +main = hspec spec + +spec :: Spec +spec = + describe "Common.padString" $ do + it "returns given string when called with default values" $ + do padString 0 0 "" False "" "test" `shouldBe` "test" + + it "truncates to max width" $ do + let maxw = 3 + givenStr = "mylongstr" + expectedStr = take maxw givenStr + padString 0 maxw "" False "" givenStr `shouldBe` expectedStr + + it "truncates to max width and concatenate with ellipsis" $ do + let maxw = 3 + givenStr = "mylongstr" + ellipsis = "..." + expectedStr = (++ ellipsis) . take 3 $ givenStr + padString 0 maxw "" False ellipsis givenStr `shouldBe` expectedStr diff --git a/test/Spec.hs b/test/Spec.hs new file mode 100644 index 0000000..52ef578 --- /dev/null +++ b/test/Spec.hs @@ -0,0 +1 @@ +{-# OPTIONS_GHC -F -pgmF hspec-discover #-} \ No newline at end of file diff --git a/xmobar.cabal b/xmobar.cabal index e95e9f3..4d6bafd 100644 --- a/xmobar.cabal +++ b/xmobar.cabal @@ -21,6 +21,48 @@ extra-source-files: readme.md, changelog.md, samples/Plugins/helloworld.config, samples/Plugins/HelloWorld.hs +test-suite XmobarTest + type: exitcode-stdio-1.0 + hs-source-dirs: + src, + test + main-is: Spec.hs + other-modules: + Xmobar, Actions, Bitmap, Config, Parsers, Commands, Localize, + XUtil, StatFS, Runnable, ColorCache, Window, Signal, + Environment, + Plugins, Plugins.BufferedPipeReader, + Plugins.CommandReader, Plugins.Date, Plugins.EWMH, + Plugins.PipeReader, Plugins.MarqueePipeReader, + Plugins.StdinReader, Plugins.XMonadLog, + Plugins.Utils, Plugins.Kbd, Plugins.Locks, Plugins.Monitors, + Plugins.Monitors.Batt, Plugins.Monitors.Common, + Plugins.Monitors.CoreCommon, Plugins.Monitors.CoreTemp, + Plugins.Monitors.CpuFreq, Plugins.Monitors.Cpu, + Plugins.Monitors.Disk, Plugins.Monitors.Mem, + Plugins.Monitors.MultiCpu, Plugins.Monitors.Net, + Plugins.Monitors.Swap, Plugins.Monitors.Thermal, + Plugins.Monitors.ThermalZone, Plugins.Monitors.Top, + Plugins.Monitors.Uptime, + Plugins.Monitors.Bright, Plugins.Monitors.CatInt + build-depends: + base == 4.*, + hspec == 2.*, + containers, + regex-compat, + process, + old-locale, + bytestring, + directory, + unix, + time, + filepath, + transformers, + X11 >= 1.6.1, + mtl >= 2.1 && < 2.3, + parsec == 3.1.*, + stm >= 2.3 && < 2.5 + source-repository head type: git location: git://github.com/jaor/xmobar.git -- cgit v1.2.3