From 9718dabe6c6d5979e3f6837ef04a39d3ad8c786c Mon Sep 17 00:00:00 2001 From: Martin Perner Date: Wed, 26 Oct 2011 01:00:32 +0200 Subject: Adding locale support to Date plugins This commits adds support for localized datetime outputs like date(1). --- src/Config.hs | 6 ++- src/Localize.hsc | 98 ++++++++++++++++++++++++++++++++++++++++++++++++ src/Plugins/DateL.hs | 35 +++++++++++++++++ src/Plugins/DateZone.hs | 2 +- src/Plugins/DateZoneL.hs | 42 +++++++++++++++++++++ 5 files changed, 180 insertions(+), 3 deletions(-) create mode 100644 src/Localize.hsc create mode 100644 src/Plugins/DateL.hs create mode 100644 src/Plugins/DateZoneL.hs (limited to 'src') diff --git a/src/Config.hs b/src/Config.hs index 4405314..cc1692e 100644 --- a/src/Config.hs +++ b/src/Config.hs @@ -27,6 +27,7 @@ import Commands import {-# SOURCE #-} Runnable import Plugins.Monitors import Plugins.Date +import Plugins.DateL import Plugins.PipeReader import Plugins.CommandReader import Plugins.StdinReader @@ -41,6 +42,7 @@ import Plugins.MBox #ifdef DATEZONE import Plugins.DateZone +import Plugins.DateZoneL #endif -- $config @@ -113,12 +115,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 :*: PipeReader :*: CommandReader :*: StdinReader :*: XMonadLog :*: EWMH :*: Kbd :*: +runnableTypes :: Command :*: Monitors :*: Date :*: DateL :*: PipeReader :*: CommandReader :*: StdinReader :*: XMonadLog :*: EWMH :*: Kbd :*: #ifdef INOTIFY Mail :*: MBox :*: #endif #ifdef DATEZONE - DateZone :*: + DateZone :*: DateZoneL :*: #endif () runnableTypes = undefined diff --git a/src/Localize.hsc b/src/Localize.hsc new file mode 100644 index 0000000..bfaa6f0 --- /dev/null +++ b/src/Localize.hsc @@ -0,0 +1,98 @@ +{-# LANGUAGE ForeignFunctionInterface #-} +----------------------------------------------------------------------------- +-- | +-- Module : Localize +-- Copyright : (C) 2011 Martin Perner +-- License : BSD-style (see LICENSE) +-- +-- Maintainer : Martin Perner +-- Stability : unstable +-- Portability : unportable +-- +-- This module provides an interface to locale information e.g. for DateL +-- +----------------------------------------------------------------------------- + +module Localize + ( setupTimeLocale, + getTimeLocale + ) where + +import Foreign +import Foreign.C +import qualified System.Locale as L + +#ifdef UTF8 +import Codec.Binary.UTF8.String +#endif + +-- get localized strings +type NlItem = CInt + +#include +foreign import ccall unsafe "langinfo.h nl_langinfo" + nl_langinfo :: NlItem -> IO CString + +#{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\ + } + +#let LIST_CTR fst,snd,idx = "( getLangInfo "fst""idx" , getLangInfo "snd""idx" )" + +getLangInfo :: NlItem -> String +#ifdef UTF8 +getLangInfo item = decodeString $ unsafePerformIO $ getLangInfo' item +#else +getLangInfo item = unsafePerformIO $ getLangInfo' item +#endif + +getLangInfo' :: NlItem -> IO String +getLangInfo' item = do + itemStr <- nl_langinfo item + peekCString itemStr + +#include +foreign import ccall unsafe "locale.h setlocale" + setlocale :: CInt -> CString -> IO CString + +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 + } diff --git a/src/Plugins/DateL.hs b/src/Plugins/DateL.hs new file mode 100644 index 0000000..d8859ed --- /dev/null +++ b/src/Plugins/DateL.hs @@ -0,0 +1,35 @@ +----------------------------------------------------------------------------- +-- | +-- Module : Plugins.DateL +-- Copyright : (c) Andrea Rossato +-- License : BSD-style (see LICENSE) +-- +-- Maintainer : Martin Perner +-- 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 4d5ce6a..f6c4f7a 100644 --- a/src/Plugins/DateZone.hs +++ b/src/Plugins/DateZone.hs @@ -8,7 +8,7 @@ -- Stability : unstable -- Portability : unportable -- --- A date plugin with localization support for Xmobar +-- A date plugin with location support for Xmobar -- -- Based on Plugins.Date -- diff --git a/src/Plugins/DateZoneL.hs b/src/Plugins/DateZoneL.hs new file mode 100644 index 0000000..2b7c467 --- /dev/null +++ b/src/Plugins/DateZoneL.hs @@ -0,0 +1,42 @@ +----------------------------------------------------------------------------- +-- | +-- Module : Plugins.DateZoneL +-- Copyright : (c) Martin Perner +-- License : BSD-style (see LICENSE) +-- +-- Maintainer : Martin Perner +-- 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 -- cgit v1.2.3