packages feed

xmobar 0.48.1 → 0.49

raw patch · 14 files changed

+224/−35 lines, 14 filesdep ~base

Dependency ranges changed: base

Files

changelog.md view
@@ -1,3 +1,11 @@+## Version 0.49 (April, 2025)++- New plugins: `ArchUpdates` and `Accordion` (thanks, Enrico Maria)+- New template variable `weatherS` for `WeatherX`.+- New Nix flake (thanks, refaelsh)+- `MPRIS`: Fix for duration reported by Spotify (thanks, Claudio)+- Base dep up to 4.20 (thanks, Alexander)+ ## Version 0.48.1 (May, 2024)  - Removing for now mouse support for `Kbd`, which can be recovered by
doc/plugins.org view
@@ -1268,9 +1268,11 @@     - Works in the same way as =Weather=, but takes an additional argument,       a list of pairs from sky conditions to their replacement (typically a       unicode string or an icon specification).-    - Use the variable =skyConditionS= to display the replacement of the-      corresponding sky condition. All other =Weather= template variables-      are available as well.+    - Use the variable =skyConditionS= or =weatherS= to display the replacement of+      the corresponding sky condition. =weatherS= uses the string returned by+      =weather= to look up a replacement, and, if that one is not found, it+      looks up the value of =skyConditionS=. All other =Weather= template+      variables are available as well.        For example: @@ -1321,7 +1323,7 @@       #+begin_src haskell         Run UVMeter "Brisbane" ["-H", "3", "-L", "3", "--low", "green", "--high", "red"] 900       #+end_src-** Other monitors+** Other monitors and plugins *** =CatInt n filename=      - Reads and displays an integer from the file whose path is =filename=@@ -1351,6 +1353,43 @@       the display of those numeric fields.     - Default template: =Up: <days>d <hours>h <minutes>m= +*** =ArchUpdates (Zero, One, Many) Rate=++  - Aliases to =arch=+  - =Zero=: a =String= to use when the system is up to date.+  - =One=: a =String= to use when only one update is available.+  - =Many=: a =String= to use when several updates are available; it must contain+    a =?= character as a placeholder for the number of updates.+  - Example:+    #+begin_src haskell+      ArchUpdates ("<fc=green>up to date</fc>",+                   "<fc=yellow>1 update</fc>,+                   "<fc=red>? updates</fc>")+                   600+    #+end_src++*** =makeAccordion Tuning [Runnable]=++  - Wraps other =Runnable= plugins and makes them all collapsible to a single string:++    [[file:accordion.gif]]++  - Aliases to =alias' tuning=, being =tuning= of type =Tuning=, so one can use multiple such "accordions"+  - **Disclaimer**: This only works for Haskell =xmobar.hs=+  - =Tuning=: the "settings", for which a default value is provided,+    #+begin_src haskell+      defaultTuning = Tuning {+          alias' = "accordion"+        , initial = True+        , expand = "<>"+        , shrink = "><"+      }+    #+end_src+  - =expand=: =String= shown when the accordion is contracted (defaults to ="<>"=).+  - =shrink=: =String= shown when the accordion is expanded (defaults to ="><"=).+  - =initial=: =Bool= to tell whether the accordion is initially expanded (defaults to =True=).+  - =[Runnable]=: a list of =Runnable= plugins+ * Interfacing with window managers   :PROPERTIES:   :CUSTOM_ID: interfacing-with-window-managers@@ -1574,8 +1613,6 @@       updates. It is thus necessary to enable =-threaded= when compiling       xmonad configuration (=xmonad.hs=), e.g. by using a custom       =~/.xmonad/build= script.--  * Executing external commands 
readme.org view
@@ -5,9 +5,6 @@   <a href="http://hackage.haskell.org/package/xmobar">     <img src="https://img.shields.io/hackage/v/xmobar.svg" alt="hackage"/>   </a>-  <a href="https://ci.codeberg.org/xmobar/xmobar">-    <img src="https://ci.codeberg.org/api/badges/xmobar/xmobar/status.svg" alt="ci"/>-  </a> </p> #+end_export @@ -203,6 +200,6 @@   This software is released under a BSD-style license. See [[https://codeberg.org/xmobar/xmobar/src/branch/master/license][license]] for more   details. -  Copyright © 2010-2024 Jose Antonio Ortega Ruiz+  Copyright © 2010-2025 Jose Antonio Ortega Ruiz    Copyright © 2007-2010 Andrea Rossato
src/Xmobar.hs view
@@ -26,6 +26,8 @@               , SignalType (..)               , module Xmobar.Config.Types               , module Xmobar.Config.Parse+              , module Xmobar.Plugins.Accordion+              , module Xmobar.Plugins.ArchUpdates               , module Xmobar.Plugins.BufferedPipeReader               , module Xmobar.Plugins.CommandReader               , module Xmobar.Plugins.Date@@ -53,6 +55,8 @@ import Xmobar.Run.Exec import Xmobar.Config.Types import Xmobar.Config.Parse+import Xmobar.Plugins.Accordion+import Xmobar.Plugins.ArchUpdates import Xmobar.Plugins.Command import Xmobar.Plugins.BufferedPipeReader import Xmobar.Plugins.CommandReader
src/Xmobar/App/Opts.hs view
@@ -1,7 +1,7 @@ ------------------------------------------------------------------------------ -- | -- Module: Xmobar.App.Opts--- Copyright: (c) 2018, 2019, 2020, 2022, 2023, 2024 Jose Antonio Ortega Ruiz+-- Copyright: (c) 2018, 2019, 2020, 2022, 2023, 2024, 2025 Jose Antonio Ortega Ruiz -- License: BSD3-style (see LICENSE) -- -- Maintainer: jao@gnu.org@@ -116,7 +116,7 @@  info :: String info = "xmobar " ++ showVersion version-        ++ "\n (C) 2010 - 2024 Jose A Ortega Ruiz"+        ++ "\n (C) 2010 - 2025 Jose A Ortega Ruiz"         ++ "\n (C) 2007 - 2010 Andrea Rossato\n "         ++ mail ++ "\n" ++ license ++ "\n" 
+ src/Xmobar/Plugins/Accordion.hs view
@@ -0,0 +1,97 @@+{-# LANGUAGE TupleSections, FlexibleContexts #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  Plugins.Monitors.Accordion+-- Copyright   :  (c) 2024 Enrico Maria De Angelis+-- License     :  BSD-style (see LICENSE)+--+-- Maintainer  :  Enrico Maria De Angelis <enricomaria.dean6elis@gmail.com>+-- Stability   :  unstable+-- Portability :  unportable+--+-- A plugin to group adjacent plugins and make them, as a whole, shrinkable to+-- an alternate text upon clicking.+--+-----------------------------------------------------------------------------++module Xmobar.Plugins.Accordion (defaultTuning, makeAccordion, Tuning(..)) where++import Control.Concurrent.Async (withAsync)+import Control.Exception (finally)+import Control.Monad (forever, join, when)+import Control.Monad.IO.Class (liftIO)+import Control.Monad.Reader (runReaderT, ask)+import Control.Monad.State.Strict (evalStateT, get, modify')+import Data.IORef (atomicModifyIORef', newIORef, readIORef)+import Data.Maybe (isJust)+import System.Directory (removeFile)+import System.Exit (ExitCode(..))+import System.Process (readProcessWithExitCode)+import Xmobar.Run.Exec (Exec(..), tenthSeconds)++-- TODO: Ideally, I'd have just `Accordion`, and not `Tuning`, but since+-- `Accordion` is polymorphic, I can't have a `defaultAccordion` constructor+-- with `plugins = []`, because that leaves  `a` undetermined.+-- So I have move all non-polymorphic typed members in `Tuning`, allowing for+-- default values at least for those members.+data Accordion a = Accordion {+    tuning :: Tuning+  , plugins :: [a]+} deriving (Show, Read)++makeAccordion :: Exec a => Tuning -> [a] -> Accordion a+makeAccordion t rs = Accordion { tuning = t, plugins = rs }++data Tuning = Tuning {+    alias' :: String+  , initial :: Bool+  , expand :: String+  , shrink :: String+} deriving (Read, Show)++defaultTuning :: Tuning+defaultTuning = Tuning {+    alias' = "accordion"+  , initial = True+  , expand = "<>"+  , shrink = "><"+}++instance (Exec a, Read a, Show a) => Exec (Accordion a) where+  alias (Accordion Tuning { alias' = name } _) = name+  start (Accordion Tuning { initial = initial'+                          , expand = expand'+                          , shrink = shrink' }+                   runnables)+        cb = do+    clicked <- newIORef Nothing+    (_, n, _) <- readProcessWithExitCode "uuidgen" [] ""+    let pipe = "/tmp/accordion-" ++ removeLinebreak n+    (_, _, _) <- readProcessWithExitCode "mkfifo" [pipe] ""+    withAsync (forever $ do (ret, _, _) <- readProcessWithExitCode "cat" [pipe] ""+                            case ret of+                              ExitSuccess -> atomicModifyIORef' clicked (const (Just (), ()))+                              ExitFailure _ -> error "how is this possible?")+              (const $ do+                  srefs <- mapM (newIORef . const "") runnables+                  foldr (\(runnable, sref) acc -> withAsync (start runnable (writeToRef sref)) (const acc))+                        (forever (do liftIO (tenthSeconds 1)+                                     clicked' <- liftIO $ readIORef clicked+                                     when (isJust clicked')+                                          (do liftIO $ clear clicked+                                              modify' not)+                                     b <- get+                                     if b then loop pipe else liftIO $ cb (click pipe expand'))+                                 `runReaderT` srefs `evalStateT` initial')+                        (zip runnables srefs))+      `finally` removeFile pipe+    where+      click file icon = "<action=`echo 1 > " ++ file ++ "`>" ++ icon ++ "</action>"+      clear = (`atomicModifyIORef'` const (Nothing, ()))+      removeLinebreak = init+      writeToRef strRef = atomicModifyIORef' strRef . const . (,())+      loop p = do+        srefs <- ask+        text <- join <$> mapM (liftIO . readIORef) srefs+        liftIO $ cb $ text ++ click p shrink'
+ src/Xmobar/Plugins/ArchUpdates.hs view
@@ -0,0 +1,41 @@+{-# LANGUAGE CPP #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  Plugins.Monitors.ArchUpdates+-- Copyright   :  (c) 2024 Enrico Maria De Angelis+-- License     :  BSD-style (see LICENSE)+--+-- Maintainer  :  Enrico Maria De Angelis <enricomaria.dean6elis@gmail.com>+-- Stability   :  unstable+-- Portability :  unportable+--+-- An ArchLinux updates availablility plugin for Xmobar+--+-----------------------------------------------------------------------------++module Xmobar.Plugins.ArchUpdates (ArchUpdates(..)) where++import System.Exit (ExitCode(..))+import System.Process (readProcessWithExitCode)+import Xmobar.Run.Exec+import Xmobar.Plugins.Command (Rate)++data ArchUpdates = ArchUpdates (String, String, String) Rate+  deriving (Read, Show)++instance Exec ArchUpdates where+    alias (ArchUpdates _ _) = "arch"+    rate (ArchUpdates _ r) = r+    run (ArchUpdates (z, o, m) _) = do+      (exit, stdout, _) <- readProcessWithExitCode "checkupdates" [] ""+      return $ case exit of+        ExitFailure 2 -> z--ero updates+        ExitFailure 1 -> "pacman: Unknown cause of failure."+        ExitSuccess -> case length $ lines stdout of+          0 -> impossible+          1 -> o+          n -> m >>= \c -> if c == '?' then show n else pure c+        _ -> impossible+        where+          impossible = error "This is impossible based on pacman manpage"
src/Xmobar/Plugins/MarqueePipeReader.hs view
@@ -60,7 +60,7 @@         Nothing -> tenthSeconds rate >> writer (drop 1 txt) sep len rate chan cb  toInfTxt :: String -> String -> String-toInfTxt line sep = concat (repeat $ line ++ " " ++ sep ++ " ")+toInfTxt line sep = cycle (line ++ " " ++ sep ++ " ")  checkPipe :: FilePath -> IO () checkPipe file = handle (\(SomeException _) -> waitForPipe) $ do
src/Xmobar/Plugins/Monitors/Mpris.hs view
@@ -28,7 +28,7 @@ import Control.Arrow ((***)) import Data.Maybe ( fromJust ) import Data.Int ( Int32, Int64 )-import Data.Word ( Word32 )+import Data.Word ( Word32, Word64 ) import System.IO.Unsafe ( unsafePerformIO )  import Control.Exception (try)@@ -136,17 +136,17 @@                              "xesam:trackNumber" -> printf "%02d" num                              _ -> (show::Int32 -> String) num             pw32 v = printf "%02d" (fromVar v::Word32)-            plen str v = let num = fromVar v in-                           case str of+            plen str num = case str of                              "mpris:length" -> formatTime (num `div` 1000000)-                             _ -> (show::Int64 -> String) num+                             _ -> show num             getStr str = case lookup str md of                 Nothing -> ""                 Just v -> case variantType v of                             TypeString -> fromVar v                             TypeInt32 -> pInt str v                             TypeWord32 -> pw32 v-                            TypeInt64 -> plen str v+                            TypeWord64 -> plen str (fromVar v :: Word64)+                            TypeInt64 -> plen str (fromVar v :: Int64)                             TypeArray TypeString ->                               let x = arrayItems (fromVar v) in                                 if null x then "" else fromVar (head x)
src/Xmobar/Plugins/Monitors/Top.hs view
@@ -3,7 +3,7 @@ ----------------------------------------------------------------------------- -- | -- Module      :  Plugins.Monitors.Top--- Copyright   :  (c) 2010, 2011, 2012, 2013, 2014, 2018, 2022 Jose A Ortega Ruiz+-- Copyright   :  (c) 2010-2014, 2018, 2022, 2025 Jose A Ortega Ruiz -- License     :  BSD-style (see LICENSE) -- -- Maintainer  :  Jose A Ortega Ruiz <jao@gnu.org>@@ -20,7 +20,7 @@  import Data.IORef (newIORef, readIORef, writeIORef) import Data.List (sortBy)-import Data.Ord (comparing)+import Data.Ord (comparing, Down (..)) import Data.Time.Clock (getCurrentTime, diffUTCTime)  import Xmobar.Plugins.Monitors.Top.Common (@@ -66,7 +66,7 @@   sortTop :: [(String, Float)] -> [(String, Float)]-sortTop =  sortBy (flip (comparing snd))+sortTop =  sortBy (comparing (Down . snd))  showMemInfo :: Float -> MemInfo -> Monitor [String] showMemInfo scale (nm, rss) =
src/Xmobar/Plugins/Monitors/Weather.hs view
@@ -66,6 +66,7 @@        , "skyCondition"        , "skyConditionS"        , "weather"+       , "weatherS"        , "tempC"        , "tempF"        , "dewPointC"@@ -221,23 +222,23 @@     errHandler :: CE.SomeException -> IO String     errHandler _ = return "<Could not retrieve data>" -formatSk :: Eq p => [(p, p)] -> p -> p-formatSk ((a,b):sks) sk = if a == sk then b else formatSk sks sk-formatSk [] sk = sk- formatWeather     :: WeatherOpts        -- ^ Formatting options from the cfg file     -> [(String,String)]  -- ^ 'SkyConditionS' for 'WeatherX'     -> [WeatherInfo]      -- ^ The actual weather info     -> Monitor String-formatWeather opts sks [WI st ss y m d h (WindInfo wc wa wm wk wkh wms) v sk we tC tF dC dF r p] =-    do cel <- showWithColors show tC+formatWeather opts sks [WI st ss y m d h wind v sk we tC tF dC dF r p] =+    do let WindInfo wc wa wm wk wkh wms = wind+       cel <- showWithColors show tC        far <- showWithColors show tF-       let sk' = formatSk sks (map toLower sk)-           we' = showWeather (weatherString opts) we+       let we' = showWeather (weatherString opts) we+           sk' = findSk sks (map toLower sk) we'+           we'' = findSk sks (map toLower we') sk'        parseTemplate [st, ss, y, m, d, h, wc, wa, wm, wk, wkh-                     , wms, v, sk, sk', we', cel, far+                     , wms, v, sk, sk', we', we'', cel, far                      , show dC, show dF, show r , show p ]+       where findSk ((a,b):xs) x df = if a == x then b else findSk xs x df+             findSk [] _ df = df formatWeather _ _ _ = getConfigValue naString  -- | Show the 'weather' field with a default string in case it was empty.
src/Xmobar/Run/Types.hs view
@@ -19,6 +19,7 @@ module Xmobar.Run.Types(runnableTypes) where  import {-# SOURCE #-} Xmobar.Run.Runnable()+import Xmobar.Plugins.ArchUpdates import Xmobar.Plugins.Command import Xmobar.Plugins.Monitors import Xmobar.Plugins.Date@@ -59,6 +60,7 @@ runnableTypes :: Command :*: Monitors :*: Date :*: PipeReader :*:                  BufferedPipeReader :*: CommandReader :*: StdinReader :*:                  XMonadLog :*: EWMH :*: Kbd :*: Locks :*: NotmuchMail :*:+                 ArchUpdates :*: #ifdef INOTIFY                  Mail :*: MBox :*: #endif
src/Xmobar/X11/Loop.hs view
@@ -170,7 +170,7 @@ runActions :: D.Actions -> A.Button -> X11.Position -> IO () runActions actions button pos =   mapM_ A.runAction $-   filter (\(A.Spawn b _) -> button `elem` b) $-   concatMap (\(a,_,_) -> a) $-   filter (\(_, from, to) -> pos' >= from && pos' <= to) actions+   concatMap+    (filter (\ (A.Spawn b _) -> button `elem` b) . (\ (a, _, _) -> a))+    (filter (\ (_, from, to) -> pos' >= from && pos' <= to) actions)   where pos' = fromIntegral pos
xmobar.cabal view
@@ -1,5 +1,5 @@ name:               xmobar-version:            0.48.1+version:            0.49 homepage:           https://codeberg.org/xmobar/xmobar synopsis:           A Minimalistic Text Based Status Bar description: 	    Xmobar is a minimalistic text based status bar.@@ -105,6 +105,7 @@     hs-source-dirs:  src      exposed-modules: Xmobar,+                     Xmobar.Plugins.Accordion,                      Xmobar.Plugins.Monitors.Common.Types,                      Xmobar.Plugins.Monitors.Common.Run,                      Xmobar.Plugins.Monitors.Common,@@ -149,6 +150,7 @@                    Xmobar.X11.Text,                    Xmobar.X11.Types,                    Xmobar.X11.Window,+                   Xmobar.Plugins.ArchUpdates,                    Xmobar.Plugins.Command,                    Xmobar.Plugins.BufferedPipeReader,                    Xmobar.Plugins.CommandReader,@@ -198,7 +200,7 @@     build-depends:                   aeson >= 1.4.7.1,                   async,-                  base >= 4.11.0 && < 4.20,+                  base >= 4.11.0 && < 4.21,                   bytestring >= 0.10.8.2,                   cairo >= 0.13,                   colour >= 2.3.6,