summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--NEWS4
-rw-r--r--README33
-rw-r--r--src/Config.hs6
-rw-r--r--src/Localize.hsc83
-rw-r--r--src/Plugins/DateL.hs35
-rw-r--r--src/Plugins/DateZone.hs50
-rw-r--r--src/Plugins/DateZoneL.hs42
-rw-r--r--xmobar.cabal2
8 files changed, 88 insertions, 167 deletions
diff --git a/NEWS b/NEWS
index 0f04c84..dc9576f 100644
--- a/NEWS
+++ b/NEWS
@@ -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]).
diff --git a/README b/README
index 48c48ed..f6d0ac0 100644
--- a/README
+++ b/README
@@ -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