diff options
| -rw-r--r-- | NEWS | 4 | ||||
| -rw-r--r-- | README | 33 | ||||
| -rw-r--r-- | src/Config.hs | 6 | ||||
| -rw-r--r-- | src/Localize.hsc | 83 | ||||
| -rw-r--r-- | src/Plugins/DateL.hs | 35 | ||||
| -rw-r--r-- | src/Plugins/DateZone.hs | 50 | ||||
| -rw-r--r-- | src/Plugins/DateZoneL.hs | 42 | ||||
| -rw-r--r-- | xmobar.cabal | 2 | 
8 files changed, 88 insertions, 167 deletions
| @@ -6,8 +6,8 @@  _New features_    - New brightness monitor, courtesy of Martin Perner. -  - New DateL, DateZone, DateZoneL plugins, for configurable timezone and -    localized datetimes, also by Martin. +  - New DateZone plugin, for configurable timezone and localized datetimes, also +    by Martin.    - New keyboard layout monitor (Kbd).  Yes, by Martin.    - Rewrite of the event handling ([issue 53], [issue 57]), also by Martin.    - Cpu monitor now also reports `iowait` field ([issue 55]). @@ -125,7 +125,7 @@ Otherwise, you'll need to install them yourself.       [alsa-mixer] package.  `with_datezone` -:    Support for other timezones. Enables the DateZone and DateZoneL plugin. +:    Support for other timezones. Enables the DateZone plugin.       Requires [timezone-olson] and [timezone-series] package.  `all_extensions` @@ -872,33 +872,18 @@ can be used in the output template as `%mydate%`    `strftime` function (or Haskell's `formatCalendarTime`).  - Sample usage: `Run Date "%a %b %_d %Y <fc=#ee9a00>%H:%M:%S</fc>" "date" 10` -`DateZone Format Alias Zone RefreshRate` +`DateZone Format Locale Zone Alias RefreshRate`  - Format is a time format string, as accepted by the standard ISO C    `strftime` function (or Haskell's `formatCalendarTime`). -- Zone is the name of the TimeZone. Assumes that the tz database is stored in -  /usr/share/zoneinfo/ -- Sample usage: -  `Run DateZone "<fc=#ee9a00>%H:%M:%S</fc>" "viennaDate" "Europa/Vienna" 10` - -`DateL Format Locale Alias RefreshRate` - -- Behaves as Date but localizes the output  - If Locale is "" the default locale of the system is used, otherwise the given -  locale -- As this plugin calls `setlocale`, there can only be one locale used, besides -  English (default of Haskell, used in Date and DateZone) with DateL and -  DateZoneL. If multiple plugin instances, with different locales, are used -  the result is a race condition, but consistent between all plugins. -- Usage with system locale: -  `Run DateL "%B" "" "date" 10` -- Usage with german locale: -  `Run DateL "%B" "de_DE.UTF-8" "date" 10` - -`DateZoneL Format Locale Alias Zone RefreshRate` - -- Behaves as DateZone but localizes the output -- Please check DateL for information's about Locale +  locale. If there are more instances of DateZone, using "" as input for Locacle +  is not recommended. +- Zone is the name of the TimeZone. It is assumed that the tz database is stored +  in /usr/share/zoneinfo/. If "" is given as Zone, the default system time is +  used. +- Sample usage: +  `Run DateZone "<fc=#ee9a00>%H:%M:%S</fc>" "GMT+1" "Europe/Vienna" "viennaTime" 10`  `CommandReader "/path/to/program" Alias` diff --git a/src/Config.hs b/src/Config.hs index cc1692e..4405314 100644 --- a/src/Config.hs +++ b/src/Config.hs @@ -27,7 +27,6 @@ import Commands  import {-# SOURCE #-} Runnable  import Plugins.Monitors  import Plugins.Date -import Plugins.DateL  import Plugins.PipeReader  import Plugins.CommandReader  import Plugins.StdinReader @@ -42,7 +41,6 @@ import Plugins.MBox  #ifdef DATEZONE  import Plugins.DateZone -import Plugins.DateZoneL  #endif  -- $config @@ -115,12 +113,12 @@ infixr :*:  -- the 'Runnable.Runnable' Read instance. To install a plugin just add  -- the plugin's type to the list of types (separated by ':*:') appearing in  -- this function's type signature. -runnableTypes :: Command :*: Monitors :*: Date :*: DateL :*: PipeReader :*: CommandReader :*: StdinReader :*: XMonadLog :*: EWMH :*: Kbd :*: +runnableTypes :: Command :*: Monitors :*: Date :*: PipeReader :*: CommandReader :*: StdinReader :*: XMonadLog :*: EWMH :*: Kbd :*:  #ifdef INOTIFY                   Mail :*: MBox :*:  #endif  #ifdef DATEZONE -                 DateZone :*: DateZoneL :*: +                 DateZone :*:  #endif                   ()  runnableTypes = undefined diff --git a/src/Localize.hsc b/src/Localize.hsc index bfaa6f0..b302cd4 100644 --- a/src/Localize.hsc +++ b/src/Localize.hsc @@ -18,7 +18,6 @@ module Localize        getTimeLocale      ) where -import Foreign  import Foreign.C  import qualified System.Locale as L @@ -36,27 +35,21 @@ foreign import ccall unsafe "langinfo.h nl_langinfo"  #{enum NlItem,    , AM_STR , PM_STR \    , D_T_FMT , D_FMT , T_FMT , T_FMT_AMPM \ -  , ABDAY_1 , ABDAY_2 , ABDAY_3 , ABDAY_4 , ABDAY_5 , ABDAY_6 , ABDAY_7 \ -  , DAY_1 , DAY_2 , DAY_3 , DAY_4 , DAY_5 , DAY_6 , DAY_7 \ -  , ABMON_1 , ABMON_2 , ABMON_3 , ABMON_4 , ABMON_5 , ABMON_6 , ABMON_7 \ -  , ABMON_8 , ABMON_9 , ABMON_10 , ABMON_11 , ABMON_12 \ -  , MON_1 , MON_2 , MON_3 , MON_4  , MON_5 , MON_6 , MON_7 , MON_8 , MON_9 \ -  , MON_10 , MON_11 , MON_12\ +  , ABDAY_1, ABDAY_7 \ +  , DAY_1, DAY_7 \ +  , ABMON_1, ABMON_12 \ +  , MON_1, MON_12\   } -#let LIST_CTR fst,snd,idx = "( getLangInfo "fst""idx" , getLangInfo "snd""idx" )" - -getLangInfo :: NlItem -> String +getLangInfo :: NlItem -> IO String +getLangInfo item = do +  itemStr <- nl_langinfo item  #ifdef UTF8 -getLangInfo item = decodeString $ unsafePerformIO $ getLangInfo' item +  str <- peekCString itemStr +  return $ decodeString str  #else -getLangInfo item = unsafePerformIO $ getLangInfo' item -#endif - -getLangInfo' :: NlItem -> IO String -getLangInfo' item = do -  itemStr <- nl_langinfo item    peekCString itemStr +#endif  #include <locale.h>  foreign import ccall unsafe "locale.h setlocale" @@ -65,34 +58,28 @@ foreign import ccall unsafe "locale.h setlocale"  setupTimeLocale :: String -> IO ()  setupTimeLocale l = withCString l (setlocale #const LC_TIME) >> return () -getTimeLocale :: L.TimeLocale -getTimeLocale = L.TimeLocale { -    L.wDays = [ #{LIST_CTR "day","abday","1"} -              , #{LIST_CTR "day","abday","2"} -              , #{LIST_CTR "day","abday","3"} -              , #{LIST_CTR "day","abday","4"} -              , #{LIST_CTR "day","abday","5"} -              , #{LIST_CTR "day","abday","6"} -              , #{LIST_CTR "day","abday","7"} -              ], -    L.months = [ #{LIST_CTR "mon","abmon","1"} -               , #{LIST_CTR "mon","abmon","2"} -               , #{LIST_CTR "mon","abmon","3"} -               , #{LIST_CTR "mon","abmon","4"} -               , #{LIST_CTR "mon","abmon","5"} -               , #{LIST_CTR "mon","abmon","6"} -               , #{LIST_CTR "mon","abmon","7"} -               , #{LIST_CTR "mon","abmon","8"} -               , #{LIST_CTR "mon","abmon","9"} -               , #{LIST_CTR "mon","abmon","10"} -               , #{LIST_CTR "mon","abmon","11"} -               , #{LIST_CTR "mon","abmon","12"} -              ], -    -- Intervals are not available from this interface -    L.intervals = L.intervals L.defaultTimeLocale, -    L.amPm = (getLangInfo amStr, getLangInfo pmStr), -    L.dateTimeFmt = getLangInfo dTFmt, -    L.dateFmt = getLangInfo dFmt, -    L.timeFmt = getLangInfo tFmt, -    L.time12Fmt = getLangInfo tFmtAmpm -  } +getTimeLocale :: IO L.TimeLocale +getTimeLocale = do +  -- assumes that the defined values are increasing by exactly one. +  -- as they are defined consecutive in an enum this is reasonable +  days   <- mapM getLangInfo [day1 .. day7] +  abdays <- mapM getLangInfo [abday1 .. abday7] + +  mons   <- mapM getLangInfo [mon1 .. mon12] +  abmons <- mapM getLangInfo [abmon1 .. abmon12] + +  amstr <- getLangInfo amStr +  pmstr <- getLangInfo pmStr +  dtfmt <- getLangInfo dTFmt +  dfmt  <- getLangInfo dFmt +  tfmt  <- getLangInfo tFmt +  tfmta <- getLangInfo tFmtAmpm + +  let t =  L.defaultTimeLocale {L.wDays  = zip days abdays +                               ,L.months = zip mons abmons +                               ,L.amPm = (amstr, pmstr) +                               ,L.dateTimeFmt = dtfmt +                               ,L.dateFmt = dfmt +                               ,L.timeFmt = tfmt +                               ,L.time12Fmt = tfmta} +  return t diff --git a/src/Plugins/DateL.hs b/src/Plugins/DateL.hs deleted file mode 100644 index d8859ed..0000000 --- a/src/Plugins/DateL.hs +++ /dev/null @@ -1,35 +0,0 @@ ------------------------------------------------------------------------------ --- | --- Module      :  Plugins.DateL --- Copyright   :  (c) Andrea Rossato --- License     :  BSD-style (see LICENSE) --- --- Maintainer  :  Martin Perner <martin@perner.cc> --- Stability   :  unstable --- Portability :  unportable --- --- A date plugin with localization for Xmobar --- ------------------------------------------------------------------------------ - -module Plugins.DateL (DateL(..)) where - -import Plugins -import Localize - -import System.Time - -data DateL = DateL String String String Int -    deriving (Read, Show) - -instance Exec DateL where -    alias (DateL _ _ a _) = a -    start (DateL f l _ r) cb = do -      setupTimeLocale l -      go -        where go = date f >>= cb >> tenthSeconds r >> go - -date :: String -> IO String -date format = do -  t <- toCalendarTime =<< getClockTime -  return $ formatCalendarTime getTimeLocale format t diff --git a/src/Plugins/DateZone.hs b/src/Plugins/DateZone.hs index f6c4f7a..86114bb 100644 --- a/src/Plugins/DateZone.hs +++ b/src/Plugins/DateZone.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE DoAndIfThenElse #-}  -----------------------------------------------------------------------------  -- |  -- Module      :  Plugins.DateZone @@ -8,13 +9,13 @@  -- Stability   :  unstable  -- Portability :  unportable  -- --- A date plugin with location support for Xmobar +-- A date plugin with localization and location support for Xmobar  --  -- Based on Plugins.Date  --  -- Usage example: in template put  -- --- > Run DateZone "%H:%M:%S" "utcDate" "UTC" 10 +-- > Run DateZone "%a %H:%M:%S" "de_DE.UTF-8" "UTC" "utcDate" 10  --  ----------------------------------------------------------------------------- @@ -22,23 +23,50 @@ module Plugins.DateZone (DateZone(..)) where  import Plugins -import System.Locale +import Localize + +import Control.Concurrent.STM  import Data.Time.LocalTime  import Data.Time.Format  import Data.Time.LocalTime.TimeZone.Olson  import Data.Time.LocalTime.TimeZone.Series -data DateZone = DateZone String String String Int +import System.IO.Unsafe +import System.Locale (TimeLocale) +import System.Time + + + +{-# NOINLINE localeLock #-} +-- ensures that only one plugin instance sets the locale +localeLock :: TMVar Bool +localeLock = unsafePerformIO (newTMVarIO False) + +data DateZone = DateZone String String String String Int      deriving (Read, Show)  instance Exec DateZone where -    alias (DateZone _ a _ _) = a -    run   (DateZone f _ z _) = date f z -    rate  (DateZone _ _ _ r) = r +    alias (DateZone _ _ _ a _) = a +    start (DateZone f l z _ r) cb = do +      lock <- atomically $ takeTMVar localeLock +      setupTimeLocale l +      locale <- getTimeLocale +      atomically $ putTMVar localeLock lock +      if z /= "" then do +        timeZone <- getTimeZoneSeriesFromOlsonFile ("/usr/share/zoneinfo/" ++ z) +        go (dateZone f locale timeZone) +       else +        go (date f locale) + +      where go func = func >>= cb >> tenthSeconds r >> go func + +date :: String -> TimeLocale -> IO String +date format loc = do +  t <- toCalendarTime =<< getClockTime +  return $ formatCalendarTime loc format t -date :: String -> String -> IO String -date format zone = do -  timeZone <- getTimeZoneSeriesFromOlsonFile ("/usr/share/zoneinfo/" ++ zone) +dateZone :: String -> TimeLocale -> TimeZoneSeries -> IO String +dateZone format loc timeZone = do    zonedTime <- getZonedTime -  return $ formatTime defaultTimeLocale format $ utcToLocalTime' timeZone $ zonedTimeToUTC zonedTime +  return $ formatTime loc format $ utcToLocalTime' timeZone $ zonedTimeToUTC zonedTime diff --git a/src/Plugins/DateZoneL.hs b/src/Plugins/DateZoneL.hs deleted file mode 100644 index 2b7c467..0000000 --- a/src/Plugins/DateZoneL.hs +++ /dev/null @@ -1,42 +0,0 @@ ------------------------------------------------------------------------------ --- | --- Module      :  Plugins.DateZoneL --- Copyright   :  (c) Martin Perner --- License     :  BSD-style (see LICENSE) --- --- Maintainer  :  Martin Perner <martin@perner.cc> --- Stability   :  unstable --- Portability :  unportable --- --- A date plugin with localization and location support for Xmobar --- --- Based on Plugins.DateZone --- ------------------------------------------------------------------------------ - -module Plugins.DateZoneL (DateZoneL(..)) where - -import Plugins - -import Localize - -import Data.Time.LocalTime -import Data.Time.Format -import Data.Time.LocalTime.TimeZone.Olson -import Data.Time.LocalTime.TimeZone.Series - -data DateZoneL = DateZoneL String String String String Int -    deriving (Read, Show) - -instance Exec DateZoneL where -    alias (DateZoneL _ _ a _ _) = a -    start (DateZoneL f l _ z r) cb = do -      setupTimeLocale l -      go -        where go = date f z >>= cb >> tenthSeconds r >> go - -date :: String -> String -> IO String -date format zone = do -  timeZone <- getTimeZoneSeriesFromOlsonFile ("/usr/share/zoneinfo/" ++ zone) -  zonedTime <- getZonedTime -  return $ formatTime getTimeLocale format $ utcToLocalTime' timeZone $ zonedTimeToUTC zonedTime diff --git a/xmobar.cabal b/xmobar.cabal index e830c02..6d3b32e 100644 --- a/xmobar.cabal +++ b/xmobar.cabal @@ -77,7 +77,7 @@ executable xmobar        Plugins.Monitors.Swap, Plugins.Monitors.Thermal,        Plugins.Monitors.ThermalZone, Plugins.Monitors.Top,        Plugins.Monitors.Uptime, Plugins.Monitors.Weather, -      Plugins.Monitors.Bright, Plugins.DateL, Plugins.DateZoneL +      Plugins.Monitors.Bright      ghc-prof-options:   -prof -auto-all | 
