15 Commits
v0.9 ... v0.9.1

Author SHA1 Message Date
Spencer Janssen
84a988da82 extra-source-files for the new manpage 2009-12-16 23:20:05 +00:00
Spencer Janssen
dbd739e41e Bump to 0.9.1 2009-12-16 23:11:10 +00:00
Spencer Janssen
d5d8d551e6 Determine numlockMask automatically, fixes #120 2009-12-16 01:21:40 +00:00
Spencer Janssen
a2ba4d8a6c Update for X11 1.5.0.0 2009-12-16 01:17:00 +00:00
Spencer Janssen
557d3edb7d Safer X11 version dependency 2009-12-16 01:03:30 +00:00
Brent Yorgey
262db2367f man/xmonad.hs: remove reference to deprecated 'dynamicLogDzen' function 2009-11-26 05:39:08 +00:00
Spencer Janssen
eddb445307 A few tweaks to --verbose-version 2009-12-08 04:07:29 +00:00
Adam Vogt
d5aadf2538 Generalize the type of (<+>). It can be used for keybindings too. 2009-12-05 23:36:11 +00:00
gwern0
a16bb44934 Main.hs +--verbose-version flag
This resolves http://code.google.com/p/xmonad/issues/detail?id=320 by adding a
--verbose-version option yielding output like "xmonad 0.9 compiled by ghc 6.10 for linux/i386"
2009-11-28 14:48:40 +00:00
Spencer Janssen
2b854ee47c Swap the order that windows are mapped/unmapped. Addresses #322 2009-11-19 02:54:40 +00:00
Spencer Janssen
02ed1cabdc Add GPL warning to GenerateManpage 2009-11-11 00:01:06 +00:00
Adam Vogt
02693d307c Add a basic header to the html manpage output 2009-10-28 03:30:42 +00:00
Adam Vogt
37dc284460 Use pandoc to convert a markdown manpage tranlation to html and man. 2009-10-28 03:06:39 +00:00
Daniel Schoepe
73e406f4a6 Support for extensible state in contrib modules. 2009-11-06 11:50:50 +00:00
Spencer Janssen
44bc9558d9 Set SIGPIPE to default in forked processes 2009-11-06 22:37:43 +00:00
11 changed files with 246 additions and 135 deletions

12
Main.hs
View File

@@ -26,6 +26,8 @@ import System.Exit (exitFailure)
import Paths_xmonad (version)
import Data.Version (showVersion)
import Graphics.X11.Xinerama (compiledWithXinerama)
#ifdef TESTING
import qualified Properties
#endif
@@ -39,15 +41,21 @@ main = do
let launch = catchIO buildLaunch >> xmonad defaultConfig
case args of
[] -> launch
["--resume", _] -> launch
("--resume":_) -> launch
["--help"] -> usage
["--recompile"] -> recompile True >>= flip unless exitFailure
["--restart"] -> sendRestart >> return ()
["--version"] -> putStrLn ("xmonad " ++ showVersion version)
["--version"] -> putStrLn $ unwords shortVersion
["--verbose-version"] -> putStrLn . unwords $ shortVersion ++ longVersion
#ifdef TESTING
("--run-tests":_) -> Properties.main
#endif
_ -> fail "unrecognized flags"
where
shortVersion = ["xmonad", showVersion version]
longVersion = [ "compiled by", compilerName, showVersion compilerVersion
, "for", arch ++ "-" ++ os
, "\nXinerama:", show compiledWithXinerama ]
usage :: IO ()
usage = do

View File

@@ -25,11 +25,11 @@ module XMonad.Config (defaultConfig) where
-- Useful imports
--
import XMonad.Core as XMonad hiding
(workspaces,manageHook,numlockMask,keys,logHook,startupHook,borderWidth,mouseBindings
(workspaces,manageHook,keys,logHook,startupHook,borderWidth,mouseBindings
,layoutHook,modMask,terminal,normalBorderColor,focusedBorderColor,focusFollowsMouse
,handleEventHook)
import qualified XMonad.Core as XMonad
(workspaces,manageHook,numlockMask,keys,logHook,startupHook,borderWidth,mouseBindings
(workspaces,manageHook,keys,logHook,startupHook,borderWidth,mouseBindings
,layoutHook,modMask,terminal,normalBorderColor,focusedBorderColor,focusFollowsMouse
,handleEventHook)
@@ -64,22 +64,6 @@ workspaces = map show [1 .. 9 :: Int]
defaultModMask :: KeyMask
defaultModMask = mod1Mask
-- | The mask for the numlock key. Numlock status is "masked" from the
-- current modifier status, so the keybindings will work with numlock on or
-- off. You may need to change this on some systems.
--
-- You can find the numlock modifier by running "xmodmap" and looking for a
-- modifier with Num_Lock bound to it:
--
-- > $ xmodmap | grep Num
-- > mod2 Num_Lock (0x4d)
--
-- Set numlockMask = 0 if you don't have a numlock key, or want to treat
-- numlock status separately.
--
numlockMask :: KeyMask
numlockMask = mod2Mask
-- | Width of the window border in pixels.
--
borderWidth :: Dimension
@@ -256,7 +240,6 @@ defaultConfig = XConfig
, XMonad.terminal = terminal
, XMonad.normalBorderColor = normalBorderColor
, XMonad.focusedBorderColor = focusedBorderColor
, XMonad.numlockMask = numlockMask
, XMonad.modMask = defaultModMask
, XMonad.keys = keys
, XMonad.logHook = logHook
@@ -264,4 +247,5 @@ defaultConfig = XConfig
, XMonad.mouseBindings = mouseBindings
, XMonad.manageHook = manageHook
, XMonad.handleEventHook = handleEventHook
, XMonad.focusFollowsMouse = focusFollowsMouse }
, XMonad.focusFollowsMouse = focusFollowsMouse
}

View File

@@ -24,6 +24,7 @@ module XMonad.Core (
XConf(..), XConfig(..), LayoutClass(..),
Layout(..), readsLayout, Typeable, Message,
SomeMessage(..), fromMessage, LayoutMessages(..),
StateExtension(..), ExtensionClass(..),
runX, catchX, userCode, userCodeDef, io, catchIO, installSignalHandlers, uninstallSignalHandlers,
withDisplay, withWindowSet, isRoot, runOnWorkspaces,
getAtom, spawn, spawnPID, getXMonadDir, recompile, trace, whenJust, whenX,
@@ -51,19 +52,25 @@ import Graphics.X11.Xlib
import Graphics.X11.Xlib.Extras (Event)
import Data.Typeable
import Data.List ((\\))
import Data.Maybe (isJust)
import Data.Maybe (isJust,fromMaybe)
import Data.Monoid
import Data.Maybe (fromMaybe)
import qualified Data.Map as M
import qualified Data.Set as S
-- | XState, the (mutable) window manager state.
data XState = XState
{ windowset :: !WindowSet -- ^ workspace list
, mapped :: !(S.Set Window) -- ^ the Set of mapped windows
, waitingUnmap :: !(M.Map Window Int) -- ^ the number of expected UnmapEvents
, dragging :: !(Maybe (Position -> Position -> X (), X ())) }
{ windowset :: !WindowSet -- ^ workspace list
, mapped :: !(S.Set Window) -- ^ the Set of mapped windows
, waitingUnmap :: !(M.Map Window Int) -- ^ the number of expected UnmapEvents
, dragging :: !(Maybe (Position -> Position -> X (), X ()))
, numlockMask :: !KeyMask -- ^ The numlock modifier
, extensibleState :: !(M.Map String (Either String StateExtension))
-- ^ stores custom state information.
--
-- The module XMonad.Utils.ExtensibleState in xmonad-contrib
-- provides additional information and a simple interface for using this.
}
-- | XConf, the (read-only) window manager configuration.
data XConf = XConf
@@ -93,7 +100,6 @@ data XConfig l = XConfig
-- should also be run afterwards. mappend should be used for combining
-- event hooks in most cases.
, workspaces :: ![String] -- ^ The list of workspaces' names
, numlockMask :: !KeyMask -- ^ The numlock modifier
, modMask :: !KeyMask -- ^ the mod modifier
, keys :: !(XConfig Layout -> M.Map (ButtonMask,KeySym) (X ()))
-- ^ The key binding: a map from key presses and actions
@@ -343,6 +349,33 @@ data LayoutMessages = Hide -- ^ sent when a layout becomes non-visi
instance Message LayoutMessages
-- ---------------------------------------------------------------------
-- Extensible state
--
-- | Every module must make the data it wants to store
-- an instance of this class.
--
-- Minimal complete definition: initialValue
class Typeable a => ExtensionClass a where
-- | Defines an initial value for the state extension
initialValue :: a
-- | Specifies whether the state extension should be
-- persistent. Setting this method to 'PersistentExtension'
-- will make the stored data survive restarts, but
-- requires a to be an instance of Read and Show.
--
-- It defaults to 'StateExtension', i.e. no persistence.
extensionType :: a -> StateExtension
extensionType = StateExtension
-- | Existential type to store a state extension.
data StateExtension =
forall a. ExtensionClass a => StateExtension a
-- ^ Non-persistent state extension
| forall a. (Read a, Show a, ExtensionClass a) => PersistentExtension a
-- ^ Persistent extension
-- ---------------------------------------------------------------------
-- | General utilities
--
@@ -473,5 +506,6 @@ installSignalHandlers = io $ do
uninstallSignalHandlers :: MonadIO m => m ()
uninstallSignalHandlers = io $ do
installHandler openEndedPipe Default Nothing
installHandler sigCHLD Default Nothing
return ()

View File

@@ -15,6 +15,7 @@
module XMonad.Main (xmonad) where
import Control.Arrow (second)
import Data.Bits
import Data.List ((\\))
import qualified Data.Map as M
@@ -93,7 +94,6 @@ xmonad initxmc = do
let layout = layoutHook xmc
lreads = readsLayout layout
initialWinset = new layout (workspaces xmc) $ map SD xinesc
maybeRead reads' s = case reads' s of
[(x, "")] -> Just x
_ -> Nothing
@@ -103,6 +103,10 @@ xmonad initxmc = do
ws <- maybeRead reads s
return . W.ensureTags layout (workspaces xmc)
$ W.mapLayout (fromMaybe layout . maybeRead lreads) ws
extState = fromMaybe M.empty $ do
("--resume" : _ : dyns : _) <- return args
vals <- maybeRead reads dyns
return . M.fromList . map (second Left) $ vals
cf = XConf
{ display = dpy
@@ -114,15 +118,19 @@ xmonad initxmc = do
, buttonActions = mouseBindings xmc xmc
, mouseFocused = False
, mousePosition = Nothing }
st = XState
{ windowset = initialWinset
, mapped = S.empty
, waitingUnmap = M.empty
, dragging = Nothing }
st = XState
{ windowset = initialWinset
, numlockMask = 0
, mapped = S.empty
, waitingUnmap = M.empty
, dragging = Nothing
, extensibleState = extState
}
allocaXEvent $ \e ->
runX cf st $ do
setNumlockMask
grabKeys
grabButtons
@@ -212,7 +220,9 @@ handle (UnmapEvent {ev_window = w, ev_send_event = synthetic}) = whenX (isClient
-- set keyboard mapping
handle e@(MappingNotifyEvent {}) = do
io $ refreshKeyboardMapping e
when (ev_request e == mappingKeyboard) grabKeys
when (ev_request e `elem` [mappingKeyboard, mappingModifier]) $ do
setNumlockMask
grabKeys
-- handle button release, which may finish dragging.
handle e@(ButtonEvent {ev_event_type = t})
@@ -318,6 +328,18 @@ scan dpy rootw = do
return $ not (wa_override_redirect wa)
&& (wa_map_state wa == waIsViewable || ic)
setNumlockMask :: X ()
setNumlockMask = do
dpy <- asks display
ms <- io $ getModifierMapping dpy
xs <- sequence [ do
ks <- io $ keycodeToKeysym dpy kc 0
if ks == xK_Num_Lock
then return (setBit 0 (fromIntegral m))
else return (0 :: KeyMask)
| (m, kcs) <- ms, kc <- kcs, kc /= 0]
modify (\s -> s { numlockMask = foldr (.|.) 0 xs })
-- | Grab the keys back
grabKeys :: X ()
grabKeys = do
@@ -329,7 +351,7 @@ grabKeys = do
kc <- io $ keysymToKeycode dpy sym
-- "If the specified KeySym is not defined for any KeyCode,
-- XKeysymToKeycode() returns zero."
when (kc /= '\0') $ mapM_ (grab kc . (mask .|.)) =<< extraModifiers
when (kc /= 0) $ mapM_ (grab kc . (mask .|.)) =<< extraModifiers
-- | XXX comment me
grabButtons :: X ()

View File

@@ -37,8 +37,8 @@ liftX = Query . lift
idHook :: ManageHook
idHook = doF id
-- | Compose two 'ManageHook's.
(<+>) :: ManageHook -> ManageHook -> ManageHook
-- | Infix 'mappend'. Compose two 'ManageHook' from right to left.
(<+>) :: Monoid m => m -> m -> m
(<+>) = mappend
-- | Compose the list of 'ManageHook's.

View File

@@ -68,7 +68,7 @@ manage w = whenX (not <$> isClient w) $ withDisplay $ \d -> do
where i = W.tag $ W.workspace $ W.current ws
mh <- asks (manageHook . config)
g <- fmap appEndo $ userCodeDef (Endo id) (runQuery mh w)
g <- appEndo <$> userCodeDef (Endo id) (runQuery mh w)
windows (g . f)
-- | unmanage. A window no longer exists, remove it from the window
@@ -155,13 +155,13 @@ windows f = do
whenJust (W.peek ws) $ \w -> io $ setWindowBorder d w fbc
mapM_ reveal visible
setTopFocus
-- hide every window that was potentially visible before, but is not
-- given a position by a layout now.
mapM_ hide (nub (oldvisible ++ newwindows) \\ visible)
mapM_ reveal visible
setTopFocus
-- all windows that are no longer in the windowset are marked as
-- withdrawn, it is important to do this after the above, otherwise 'hide'
-- will overwrite withdrawnState with iconicState
@@ -389,13 +389,13 @@ isClient w = withWindowSet $ return . W.member w
-- (numlock and capslock)
extraModifiers :: X [KeyMask]
extraModifiers = do
nlm <- asks (numlockMask . config)
nlm <- gets numlockMask
return [0, nlm, lockMask, nlm .|. lockMask ]
-- | Strip numlock\/capslock from a mask
cleanMask :: KeyMask -> X KeyMask
cleanMask km = do
nlm <- asks (numlockMask . config)
nlm <- gets numlockMask
return (complement (nlm .|. lockMask) .&. km)
-- | Get the 'Pixel' value for a named color
@@ -413,9 +413,13 @@ restart :: String -> Bool -> X ()
restart prog resume = do
broadcastMessage ReleaseResources
io . flush =<< asks display
args <- if resume then gets (("--resume":) . return . showWs . windowset) else return []
let wsData = show . W.mapLayout show . windowset
maybeShow (t, Right (PersistentExtension ext)) = Just (t, show ext)
maybeShow (t, Left str) = Just (t, str)
maybeShow _ = Nothing
extState = return . show . catMaybes . map maybeShow . M.toList . extensibleState
args <- if resume then gets (\s -> "--resume":wsData s:extState s) else return []
catchIO (executeFile prog True args Nothing)
where showWs = show . W.mapLayout show
------------------------------------------------------------------------
-- | Floating layer support

View File

@@ -1,57 +0,0 @@
./" man page created by David Lazar on April 24, 2007
./" uses ``tmac.an'' macro set
.TH xmonad 1 "8 September 09"\
___RELEASE___\
"xmonad manual"
.SH NAME
xmonad \- a tiling window manager
.SH DESCRIPTION
.PP
\fBxmonad\fR is a minimalist tiling window manager for X, written in Haskell. Windows are managed using automatic layout algorithms, which can be dynamically reconfigured. At any time windows are arranged so as to maximize the use of screen real estate. All features of the window manager are accessible purely from the keyboard: a mouse is entirely optional. \fBxmonad\fR is configured in Haskell, and custom layout algorithms may be implemented by the user in config files. A principle of \fBxmonad\fR is predictability: the user should know in advance precisely the window arrangement that will result from any action.
.PP
By default, \fBxmonad\fR provides three layout algorithms: tall, wide and fullscreen. In tall or wide mode, windows are tiled and arranged to prevent overlap and maximize screen use. Sets of windows are grouped together on virtual screens, and each screen retains its own layout, which may be reconfigured dynamically. Multiple physical monitors are supported via Xinerama, allowing simultaneous display of a number of screens.
.PP
By utilizing the expressivity of a modern functional language with a rich static type system, \fBxmonad\fR provides a complete, featureful window manager in less than 1200 lines of code, with an emphasis on correctness and robustness. Internal properties of the window manager are checked using a combination of static guarantees provided by the type system, and type-based automated testing. A benefit of this is that the code is simple to understand, and easy to modify.
.SH USAGE
.PP
\fBxmonad\fR places each window into a "workspace". Each workspace can have any number of windows, which you can cycle though with mod-j and mod-k. Windows are either displayed full screen, tiled horizontally, or tiled vertically. You can toggle the layout mode with mod-space, which will cycle through the available modes.
.PP
You can switch to workspace N with mod-N. For example, to switch to workspace 5, you would press mod-5. Similarly, you can move the current window to another workspace with mod-shift-N.
.PP
When running with multiple monitors (Xinerama), each screen has exactly 1 workspace visible. mod-{w,e,r} switch the focus between screens, while shift-mod-{w,e,r} move the current window to that screen. When \fBxmonad\fR starts, workspace 1 is on screen 1, workspace 2 is on screen 2, etc. When switching workspaces to one that is already visible, the current and visible workspaces are swapped.
.PP
.SS Flags
\fBxmonad\fR has several flags which you may pass to the executable. These flags are:
.TP
\fB--recompile
Recompiles your configuration in ~/.xmonad/xmonad.hs
\fB--restart
Causes the currently running xmonad process to restart
.TP
\fB--version
Display version of \fBxmonad\fR.
.SS Default keyboard bindings
___KEYBINDINGS___
.SH EXAMPLES
To use \fBxmonad\fR as your window manager add:
.RS
exec xmonad
.RE
to your \fI~/.xinitrc\fR file
.SH CUSTOMIZATION
\fBxmonad\fR is customized in ~/.xmonad/xmonad.hs, and then restarting with mod-q.
.PP
You can find many extensions to the core feature set in the xmonad-contrib package, available through your package manager or from http://xmonad.org/.
.SS "Modular Configuration"
As of \fBxmonad-0.9\fR, any additional Haskell modules may be placed in \fI~/.xmonad/lib/\fR are available in GHC's searchpath. Hierarchical modules are supported: for example, the file \fI~/.xmonad/lib/XMonad/Stack/MyAdditions.hs\fR could contain:
.RS
.nf
module XMonad.Stack.MyAdditions (function1) where
function1 = error "function1: Not implemented yet!"
.fi
.RE
.PP
Your xmonad.hs may then \fBimport XMonad.Stack.MyAdditions\fR as if that module was contained within \fBxmonad\fR or \fBxmonad-contrib\fR.
.SH BUGS
Probably. If you find any, please report them: http://code.google.com/p/xmonad/issues/list

99
man/xmonad.1.markdown Normal file
View File

@@ -0,0 +1,99 @@
#Name
xmonad - a tiling window manager
#Description
_xmonad_ is a minimalist tiling window manager for X, written in Haskell.
Windows are managed using automatic layout algorithms, which can be
dynamically reconfigured. At any time windows are arranged so as to
maximize the use of screen real estate. All features of the window manager
are accessible purely from the keyboard: a mouse is entirely optional.
_xmonad_ is configured in Haskell, and custom layout algorithms may be
implemented by the user in config files. A principle of _xmonad_ is
predictability: the user should know in advance precisely the window
arrangement that will result from any action.
By default, _xmonad_ provides three layout algorithms: tall, wide and
fullscreen. In tall or wide mode, windows are tiled and arranged to prevent
overlap and maximize screen use. Sets of windows are grouped together on
virtual screens, and each screen retains its own layout, which may be
reconfigured dynamically. Multiple physical monitors are supported via
Xinerama, allowing simultaneous display of a number of screens.
By utilizing the expressivity of a modern functional language with a rich
static type system, _xmonad_ provides a complete, featureful window manager
in less than 1200 lines of code, with an emphasis on correctness and
robustness. Internal properties of the window manager are checked using a
combination of static guarantees provided by the type system, and
type-based automated testing. A benefit of this is that the code is simple
to understand, and easy to modify.
#Usage
_xmonad_ places each window into a "workspace". Each workspace can have
any number of windows, which you can cycle though with mod-j and mod-k.
Windows are either displayed full screen, tiled horizontally, or tiled
vertically. You can toggle the layout mode with mod-space, which will cycle
through the available modes.
You can switch to workspace N with mod-N. For example, to switch to
workspace 5, you would press mod-5. Similarly, you can move the current
window to another workspace with mod-shift-N.
When running with multiple monitors (Xinerama), each screen has exactly 1
workspace visible. mod-{w,e,r} switch the focus between screens, while
shift-mod-{w,e,r} move the current window to that screen. When _xmonad_
starts, workspace 1 is on screen 1, workspace 2 is on screen 2, etc. When
switching workspaces to one that is already visible, the current and
visible workspaces are swapped.
##Flags
xmonad has several flags which you may pass to the executable.
These flags are:
--recompile
: Recompiles your configuration in _~/.xmonad/xmonad.hs_
--restart
: Causes the currently running _xmonad_ process to restart
--version
: Display version of _xmonad_
--verbose-version
: Display detailed version of _xmonad_
##Default keyboard bindings
___KEYBINDINGS___
#Examples
To use xmonad as your window manager add to your _~/.xinitrc_ file:
> exec xmonad
#Customization
xmonad is customized in ~/.xmonad/xmonad.hs, and then restarting
with mod-q.
You can find many extensions to the core feature set in the xmonad-
contrib package, available through your package manager or from
[xmonad.org].
##Modular Configuration
As of _xmonad-0.9_, any additional Haskell modules may be placed in
_~/.xmonad/lib/_ are available in GHC's searchpath. Hierarchical modules
are supported: for example, the file
_~/.xmonad/lib/XMonad/Stack/MyAdditions.hs_ could contain:
> module XMonad.Stack.MyAdditions (function1) where
> function1 = error "function1: Not implemented yet!"
Your xmonad.hs may then import XMonad.Stack.MyAdditions as if that
module was contained within xmonad or xmonad-contrib.
#Bugs
Probably. If you find any, please report them to the [bugtracker]
[xmonad.org]: http://xmonad.org
[bugtracker]: http://code.google.com/p/xmonad/issues/list

View File

@@ -34,21 +34,6 @@ myBorderWidth = 1
--
myModMask = mod1Mask
-- The mask for the numlock key. Numlock status is "masked" from the
-- current modifier status, so the keybindings will work with numlock on or
-- off. You may need to change this on some systems.
--
-- You can find the numlock modifier by running "xmodmap" and looking for a
-- modifier with Num_Lock bound to it:
--
-- > $ xmodmap | grep Num
-- > mod2 Num_Lock (0x4d)
--
-- Set numlockMask = 0 if you don't have a numlock key, or want to treat
-- numlock status separately.
--
myNumlockMask = mod2Mask
-- The default number of workspaces (virtual screens) and their names.
-- By default we use numeric strings, but any string may be used as a
-- workspace name. The number of workspaces is determined by the length
@@ -239,11 +224,7 @@ myEventHook = mempty
-- Status bars and logging
-- Perform an arbitrary action on each internal state change or X event.
-- See the 'DynamicLog' extension for examples.
--
-- To emulate dwm's status bar
--
-- > logHook = dynamicLogDzen
-- See the 'XMonad.Hooks.DynamicLog' extension for examples.
--
myLogHook = return ()
@@ -276,7 +257,6 @@ defaults = defaultConfig {
focusFollowsMouse = myFocusFollowsMouse,
borderWidth = myBorderWidth,
modMask = myModMask,
numlockMask = myNumlockMask,
workspaces = myWorkspaces,
normalBorderColor = myNormalBorderColor,
focusedBorderColor = myFocusedBorderColor,

View File

@@ -1,7 +1,14 @@
-- Unlike the rest of xmonad, this file is copyright under the terms of the
-- GPL.
--
-- Generates man/xmonad.1 from man/xmonad.1.in by filling the list of
-- keybindings with values scraped from Config.hs
--
-- Uses cabal to grab the xmonad version from xmonad.cabal
--
-- Uses pandoc to convert the "xmonad.1.markdown" to "xmonad.1"
--
-- Format for the docstrings in Config.hs takes the following form:
--
-- -- mod-x %! Frob the whatsit
@@ -14,8 +21,8 @@
-- [ ((modMask .|. shiftMask, xK_Return), spawn "xterm") -- %! Launch an xterm
--
-- Here, mod-shift-return will be used as the keybinding name.
--
import Control.Monad
import Control.Applicative
import Text.Regex.Posix
import Data.Char
import Data.List
@@ -27,6 +34,10 @@ import Distribution.PackageDescription
import Text.PrettyPrint.HughesPJ
import Distribution.Text
import Text.Pandoc
releaseDate = "25 October 09"
trim :: String -> String
trim = reverse . dropWhile isSpace . reverse . dropWhile isSpace
@@ -42,16 +53,42 @@ allBindings :: String -> [(String, String)]
allBindings xs = map (binding . map trim) (xs =~ "(.*)--(.*)%!(.*)")
-- FIXME: What escaping should we be doing on these strings?
troff :: (String, String) -> String
troff (key, desc) = ".IP\n \\fB" ++ key ++ "\\fR\n" ++ desc ++ "\n"
markdownDefn :: (String, String) -> String
markdownDefn (key, desc) = key ++ "\n: " ++ desc
replace :: Eq a => a -> a -> [a] -> [a]
replace x y = map (\a -> if a == x then y else a)
-- rawSystem "pandoc" ["--read=markdown","--write=man","man/xmonad.1.markdown"]
main = do
releaseName <- ((' ':) . (++" \\") . show . disp . package . packageDescription) `liftM` readPackageDescription normal "xmonad.cabal"
releaseName <- (show . disp . package . packageDescription)
`liftM`readPackageDescription normal "xmonad.cabal"
keybindings <- (intercalate "\n\n" . map markdownDefn . allBindings)
`liftM` readFile "./XMonad/Config.hs"
troffBindings <- (concatMap troff . allBindings) `liftM` readFile "./XMonad/Config.hs"
let manHeader = unwords [".TH xmonad 1","\""++releaseDate++"\"",releaseName,"\"xmonad manual\""]
writeOpts = defaultWriterOptions -- { writerLiterateHaskell = True }
let sed = unlines . replace "___RELEASE___\\" releaseName . replace "___KEYBINDINGS___" troffBindings . lines
readFile "./man/xmonad.1.in" >>= return . sed >>= writeFile "./man/xmonad.1"
parsed <- readMarkdown defaultParserState { stateLiterateHaskell = True }
. unlines
. replace "___KEYBINDINGS___" keybindings
. lines
<$> readFile "./man/xmonad.1.markdown"
writeFile "./man/xmonad.1"
. (manHeader ++)
. writeMan writeOpts
$ parsed
putStrLn "Documentation created: man/xmonad.1"
writeFile "./man/xmonad.1.html"
. writeHtmlString writeOpts
{ writerHeader = "<h1>"++releaseName++"</h1>"++
"<p>Section: xmonad manual (1)<br>"++
"Updated: "++releaseDate++"</p>"++
"<hr>"
, writerStandalone = True
, writerTableOfContents = True }
$ parsed
putStrLn "Documentation created: man/xmonad.1.html"

View File

@@ -1,5 +1,5 @@
name: xmonad
version: 0.9
version: 0.9.1
homepage: http://xmonad.org
synopsis: A tiling window manager
description:
@@ -18,7 +18,7 @@ license-file: LICENSE
author: Spencer Janssen
maintainer: xmonad@haskell.org
extra-source-files: README TODO CONFIG STYLE tests/loc.hs tests/Properties.hs
man/xmonad.1.in man/xmonad.1 man/xmonad.html
man/xmonad.1.markdown man/xmonad.1 man/xmonad.1.html
util/GenerateManpage.hs
cabal-version: >= 1.2
build-type: Simple
@@ -46,7 +46,7 @@ library
build-depends: base < 4 && >=3, containers, directory, process, filepath
else
build-depends: base < 3
build-depends: X11>=1.4.6.1, mtl, unix
build-depends: X11>=1.5.0.0 && < 1.6, mtl, unix
ghc-options: -funbox-strict-fields -Wall
ghc-prof-options: -prof -auto-all