Updates...

Ilya Portnov [2011-05-15 07:29:07]
Updates...
Filename
lib/AppGroups.hs
lib/CommonFunctions.hs
lib/GroupsSetup.hs
lib/KeyBindings.hs
lib/Themes.hs
xmonad.hs
diff --git a/lib/AppGroups.hs b/lib/AppGroups.hs
index 7040f95..3ad3086 100644
--- a/lib/AppGroups.hs
+++ b/lib/AppGroups.hs
@@ -1,9 +1,9 @@
 {-# LANGUAGE ExistentialQuantification, TypeSynonymInstances, FlexibleInstances #-}
 module AppGroups
-  (Key, App (..), Apps, Condition (..), Cond (..), Regex (..),
+  (Key, App (..), Apps, Condition (..), Cond (..),
    query,
    oneOf, apps2hooks, apps2keys,
-   selectAppGroup,
+   selectAppGroup, runNewApp,
    switchToApp,
    doFullscreen)
   where
@@ -18,7 +18,7 @@ import qualified XMonad.StackSet as W
 import XMonad.Actions.GridSelect
 import XMonad.Actions.DynamicWorkspaces
 import XMonad.Util.WindowProperties
--- import XMonad.Hooks.ManageHelpers hiding (C)
+import XMonad.Util.WindowPropertiesRE

 import CommonFunctions ((~?), selectOneWindow)

@@ -65,30 +65,13 @@ instance Condition String where
 instance Condition Property where
   toQuery p = propertyToQuery p

--- | Regular expression over condition
-data (Condition a) => Regex a = Regex a
-
-instance (Show a, Condition a) => Show (Regex a) where
-  show (Regex a) = show a
-
-instance Condition (Regex String) where
-  toQuery (Regex s) = className ~? s
+instance Condition PropertyRE where
+  toQuery (RE p) = propertyToQueryRE p

 -- | Query WM_WINDOW_ROLE atom
 role :: Query String
 role = stringProperty "WM_WINDOW_ROLE"

-instance Condition (Regex Property) where
-  toQuery (Regex (Title s)) = title ~? s
-  toQuery (Regex (Resource s)) = resource ~? s
-  toQuery (Regex (ClassName s)) = className ~? s
-  toQuery (Regex (Role s)) = role ~? s
-  toQuery (Regex (Machine s)) = stringProperty "WM_CLIENT_MACHINE" ~? s
-  toQuery (Regex (And p1 p2)) = toQuery p1 <&&> toQuery p2
-  toQuery (Regex (Or p1 p2)) = toQuery p1 <||> toQuery p2
-  toQuery (Regex (Not p)) = not `fmap` toQuery p
-  toQuery (Regex (Const b)) = return b
-
 -- | Turn any X () operation on window into ManageHook
 fromWindowOp :: (Window -> X()) -> ManageHook
 fromWindowOp fn = ask >>= \w -> liftX (fn w) >> doF id
@@ -176,14 +159,35 @@ groupName (_ :-> wksp)     = wksp
 groupName (Float app)      = groupName app
 groupName (Named _ name)   = name

+appWorkspace :: App -> Maybe WorkspaceId
+appWorkspace (On app _)       = appWorkspace app
+appWorkspace (_ ::: _)        = Nothing
+appWorkspace (_ :>> _)        = Nothing
+appWorkspace (Group _)        = Nothing
+appWorkspace (_ :-> wksp)     = Just wksp
+appWorkspace (Float app)      = appWorkspace app
+appWorkspace (Fullscreen app) = appWorkspace app
+appWorkspace (Named app _)    = appWorkspace app
+
+appAction :: App -> Maybe (X ())
+appAction (On app _)       = appAction app
+appAction (command ::: app) = Just $ spawn command
+appAction (action  :>> _)  = Just action
+appAction (Group _)        = Nothing
+appAction (Fullscreen app) = appAction app
+appAction (Named app _)    = appAction app
+appAction (Float app)      = appAction app
+appAction (app :-> _)      = appAction app
+
 runApp :: App -> X ()
-runApp (On app _)       = runApp app
-runApp (command ::: _)  = spawn command
-runApp (action  :>> _)  = action
-runApp (Group _)        = return ()
-runApp (Fullscreen app) = runApp app
-runApp (app :-> _)      = runApp app
-runApp (Named app _)    = runApp app
+runApp (command ::: _) = spawn command
+runApp (app :-> wksp)  = runApp  app
+runApp (action  :>> _) = action
+runApp (On app _)      = runApp app
+runApp (Group _)       = return ()
+runApp (Fullscreen ap) = runApp ap
+runApp (Float app)     = runApp app
+runApp (Named app _)   = runApp app

 apps2hooks :: Apps -> [ManageHook]
 apps2hooks lst = map appHook lst
@@ -230,7 +234,21 @@ selectAppGroup gscA gscW apps = do
     group <- gridselect gscA $ zip names nonempty
     whenJust group $ \app ->
       selectWithQuery gscW (query app) (runApp app)
-  where
-    isNotEmpty :: App -> X Bool
-    isNotEmpty group = (not . null) `fmap` matchingWindows (query group)
+
+isNotEmpty :: App -> X Bool
+isNotEmpty group = (not . null) `fmap` matchingWindows (query group)
+
+shouldRun :: App -> X Bool
+shouldRun group = do
+  ws <- matchingWindows (query group)
+  if null ws
+    then return $ isJust $ appAction group
+    else return False
+
+runNewApp :: GSConfig App -> Apps -> X ()
+runNewApp gsconfig apps = do
+    empty <- filterM shouldRun apps
+    let names = map groupName empty
+    selected <- gridselect gsconfig $ zip names empty
+    whenJust selected runApp

diff --git a/lib/CommonFunctions.hs b/lib/CommonFunctions.hs
index d0cde73..a437306 100644
--- a/lib/CommonFunctions.hs
+++ b/lib/CommonFunctions.hs
@@ -7,7 +7,8 @@ module CommonFunctions
   gotoWorkspace,
   selectOneWindow, searchInWorkspace,
   specialMove,
-  vimsessions, textEditors,
+  vimsession, vimsessions, textEditors,
+  edit_config,
   recent,
   (~?),
   isFloat,
@@ -36,6 +37,7 @@ import XMonad.Util.NamedWindows

 import XMonad.Actions.DynamicWorkspaces
 import XMonad.Actions.GridSelect
+import XMonad.Actions.SpawnOn

 import Themes

@@ -144,6 +146,9 @@ returnToCurrent c s = W.view curtag s
 curstack ::  W.StackSet i l a sid sd -> Maybe (W.Stack a)
 curstack s = W.stack $ W.workspace $ W.current s

+getCurrentWorkspace :: X WorkspaceId
+getCurrentWorkspace = withWindowSet (\ws -> return $ W.tag $ W.workspace $ W.current ws)
+
 emptyCurrentWorkspace :: (Eq s) => W.StackSet String l a s sd -> W.StackSet String l a s sd
 emptyCurrentWorkspace s = returnToCurrent s (addStackToTarget "trash" (curstack s) $ emptyCurrentWs s)

@@ -202,15 +207,21 @@ recent types = "recently-used.py " ++ unwords (map mime types)
              ("doc", "application/msword application/vnd.oasis.opendocument.text"),
              ("png", "image/png")]

+-- | Open specified GVim session
+vimsession :: String -> X ()
+vimsession name = do
+  home <- io $ getEnv "HOME"
+  let path = home </> ".vim/sessions" </> (name ++ ".vimsession")
+  spawn ("gvim -S " ++ path)
+
 -- | Open selected GVim session
 vimsessions :: X ()
 vimsessions = do
   home <- io $ getEnv "HOME"
   paths <- io $ (concat . fst) `fmap` globDir [compile "*.vimsession"] (home </> ".vim/sessions")
-  let actions  = map ("gvim -S " ++) paths
-      sessions = map (dropExtension . takeFileName) paths
-  selected <- gridselect myGSConfig $ zip sessions actions
-  whenJust selected spawn
+  let sessions = map (dropExtension . takeFileName) paths
+  selected <- gridselect myGSConfig $ zip sessions sessions
+  whenJust selected vimsession

 -- | Run the selected text editor
 textEditors ::  X ()
@@ -246,10 +257,19 @@ trashWindow = do

 -- | On window unmap, remove current workspace if it's empty.
 unmapEventHook :: Event -> X All
-unmapEventHook (UnmapEvent {}) = removeEmptyWorkspace >> return (All True)
+unmapEventHook (UnmapEvent {}) = do
+  current <- getCurrentWorkspace
+  when (current /= "dashboard") removeEmptyWorkspace
+  return (All True)
 unmapEventHook _ = return (All True)

 -- | Regular expressions matching for ManageHooks
 (~?) :: (Functor f) => f String -> String -> f Bool
 q ~? x = fmap (=~ x) q

+edit_config :: X ()
+edit_config = do
+  vimsession "xmonad"
+  spawnOn "text" =<< asks (terminal . config)
+
+
diff --git a/lib/GroupsSetup.hs b/lib/GroupsSetup.hs
index 54f7163..d8d54e4 100644
--- a/lib/GroupsSetup.hs
+++ b/lib/GroupsSetup.hs
@@ -1,35 +1,37 @@
 {-# LANGUAGE NoMonomorphismRestriction, FlexibleContexts #-}
 module GroupsSetup where

+import XMonad.Util.WindowProperties
+import XMonad.Util.WindowPropertiesRE
+
 import AppGroups
-import CommonFunctions (textEditors, recent)
+import CommonFunctions (textEditors, recent, edit_config)

-regex ::  (Condition (Regex a), Condition a) => a -> Cond
-regex = C . Regex
+regex = C . RE . ClassName

 defaultFM :: String
 defaultFM = "konqueror --profile filemanagement"

 myApps =
   [ "iceweasel" ::: [C "Epiphany-browser", C "Kontact", C "Iceweasel",
-                     C "Firefox", C "Opera", C "Arora" ]     :-> "inet"  `On` "M1-x w" `Named` "internet",
-    "icedove"   ::: [C "Icedove", C "Kontact" ]              :-> "inet"  `On` "M1-x y" `Named` "mail",
-    "rssowl"   ::: [C "Liferea", C "RSSOwl"]                 :-> "inet"                    `Named` "rss",
-    "transmission-gtk" ::: [regex "Transmission"]                    :-> "torrents" `On` "M1-x r",
+                     C "Firefox", C "Opera", C "Arora" ]     :-> "inet"     `On` "M1-x w" `Named` "internet",
+    "icedove"   ::: [C "Icedove", C "Kontact" ]              :-> "inet"     `On` "M1-x y" `Named` "mail",
+    "rssowl"   ::: [C "Liferea", C "RSSOwl"]                 :-> "inet"                   `Named` "rss",
+    "transmission-gtk" ::: [regex "Transmission"]            :-> "torrents" `On` "M1-x r",
     Group         [C "Inkscape", C "Eog", C "Gwenview", C "Dia",
                    C "MyPaint"]                              :-> "graphics" `On` "M1-x d",
-    Group         [regex "Gimp"]                             :-> "gimp"  `On` "M1-x g",
-    Group         [C "F-spot",C "Digikam"]                   :-> "photo" `On` "M1-x p",
-    "gnome-terminal" ::: [C "Gnome-terminal", C "Konsole"]   :-> "term"  `On` "M1-x t",
+    Group         [regex "Gimp"]                             :-> "gimp"     `On` "M1-x g",
+    Group         [C "F-spot",C "Digikam"]                   :-> "photo"    `On` "M1-x p",
+    "gnome-terminal" ::: [C "Gnome-terminal", C "Konsole"]   :-> "term"     `On` "M1-x t",
     textEditors :>> [C "Gedit", C "Leafpad",
-          C "Gvim", C "Kate", C "KWrite", C "Emacs"]         :-> "text"  `On` "M1-x e",
-    recent ["doc"] ::: [regex "libreoffice", C "TeXmacs"]    :-> "office" `On` "M1-x o",
-    recent ["pdf","djvu"] ::: [C "Evince", C "Okular"]       :-> "docs"  `On` "M1-x k",
+          C "Gvim", C "Kate", C "Kwrite", C "Emacs"]         :-> "text"     `On` "M1-x e",
+    recent ["doc"] ::: [regex "libreoffice", C "TeXmacs"]    :-> "office"   `On` "M1-x o",
+    recent ["pdf","djvu"] ::: [C "Evince", C "Okular"]       :-> "docs"     `On` "M1-x k",
     defaultFM ::: [C "Nautilus", C "Dolphin", C "Konqueror",
-                   C "Krusader"]                             :-> "files" `On` "M1-x f",
+                   C "Krusader"]                             :-> "files"    `On` "M1-x f",
     Group         [C "Amarok", C "Rhythmbox",
-                   regex "Audacious" ]                       :-> "music" `On` "M1-x a",
-    Group         [C "MPlayer", C "Totem"]                   :-> "video" `On` "M1-x v",
-    Group         [C "Wxmaxima"]                             :-> "math"  `On` "M1-x m",
-    "pidgin"  ::: [C "Pidgin", C "Kopete"]                   :-> "im"    `On` "M1-x i" ]
+                   regex "Audacious" ]                       :-> "music"    `On` "M1-x a",
+    Group         [C "MPlayer", C "Totem"]                   :-> "video"    `On` "M1-x v",
+    Group         [C "Wxmaxima"]                             :-> "math"     `On` "M1-x m",
+    "pidgin"  ::: [C "Pidgin", C "Kopete"]                   :-> "im"       `On` "M1-x i"]

diff --git a/lib/KeyBindings.hs b/lib/KeyBindings.hs
index 9889250..6fa0cfd 100644
--- a/lib/KeyBindings.hs
+++ b/lib/KeyBindings.hs
@@ -32,7 +32,7 @@ import XMonad.Prompt.Window
 import CommonFunctions
 import Mouse
 import Themes      (myXPConfig, myGSConfig, searchGS)
-import AppGroups   (switchToApp)
+import AppGroups   (switchToApp, runNewApp)
 import GroupsSetup (myApps)

 workspaceOrder = ["inet","text","files","im","term"]
@@ -68,6 +68,7 @@ addKeys = [--           ("M1-<F2>",         gnomeRun),
           ("M1-<F2>",         spawn "gmrun"),
           ("<Pause>",         spawn "qwerty.py -a -f -g 640x400"),
           ("M-v",             vimsessions),
+          ("M-a",             runNewApp searchGS myApps),

           -- close focused window
           ("M1-<F4>",         killIfNot (Role "buddy_list")),
@@ -83,14 +84,13 @@ addKeys = [--           ("M1-<F2>",         gnomeRun),

           ("M-b",             sendMessage $ ToggleStruts),

-          -- Focus urgent window
-          ("M-<F12>",         focusUrgent),
+          ("M1-e",             windows (W.greedyView "dashboard")),

           -- Bring any window to current workspace
-          ("M1-w",            windowPromptBring myXPConfig),
-          ("M1-x x",          searchInWorkspace searchGS),
-          ("M1-z",            goToSelected searchGS),
-          ("M-z",             gridselectWorkspace searchGS W.greedyView),
+          ("M1-w",            bringSelected searchGS),
+          ("M1-<Tab>",        searchInWorkspace searchGS),
+          ("M-<Tab>",         gridselectWorkspace searchGS W.greedyView),
+          ("M1-/",            goToSelected searchGS),

           ("M-<Backspace>",   nextMatch History (return True)),

@@ -99,7 +99,6 @@ addKeys = [--           ("M1-<F2>",         gnomeRun),

           -- Move focus to the next window
 --           ("M1-<Tab>",        windows W.focusDown),
-          ("M1-<Tab>",        searchInWorkspace searchGS),
           ("M-j",             windows W.focusDown),
           ("M-k",             windows W.focusUp  ),

@@ -125,8 +124,6 @@ addKeys = [--           ("M1-<F2>",         gnomeRun),

           ("M-M1-u",          withFocused (sendMessage . UnMerge)),

-          ("M-M1-u",          withFocused (sendMessage . UnMergeAll)),
-
           -- Shrink/expand the master area
           ("M-e",             sendMessage Shrink),
           ("M-r",             sendMessage Expand),
@@ -134,7 +131,7 @@ addKeys = [--           ("M1-<F2>",         gnomeRun),
           -- Push window back into tiling
           ("M-S-f",           withFocused $ windows . W.sink),

-          ("M-<Home>",        spawn "gvim ~/.xmonad/xmonad.hs"),
+          ("M-<Home>",        edit_config),
           ("M-l",             spawn "xscreensaver-command -lock"),


diff --git a/lib/Themes.hs b/lib/Themes.hs
index 003d740..47c50f1 100644
--- a/lib/Themes.hs
+++ b/lib/Themes.hs
@@ -28,7 +28,7 @@ searchGS = defaultGSConfig {
 -----------------------------------------------------------------------
 -- Some general settings
 myWorkspaces :: [WorkspaceId]
-myWorkspaces = ["main"]
+myWorkspaces = ["dashboard"]

 myFocusedBorderColor :: String
 myFocusedBorderColor = "#E3A775"
diff --git a/xmonad.hs b/xmonad.hs
index c7cdb0c..d56e8ac 100644
--- a/xmonad.hs
+++ b/xmonad.hs
@@ -6,6 +6,7 @@ import XMonad.Config.Kde (kde4Config)

 import XMonad.Actions.GroupNavigation (historyHook)
 import XMonad.Actions.UpdatePointer
+import XMonad.Actions.SpawnOn

 -- Import hooks to support EWMH and other compatibility hooks
 import XMonad.Hooks.EwmhDesktops (ewmh)
@@ -45,7 +46,7 @@ main =  do
       -- hooks, layouts
         layoutHook         = myLayout,
         handleEventHook    = unmapEventHook <+> minimizeEventHook,
-        manageHook         = baseManageHook <+> myManageHook,
+        manageHook         = manageSpawn <+> baseManageHook <+> myManageHook,
         logHook            = do
                                 baseLogHook
                                 updatePointer (TowardsCentre 0.5 0.5)
ViewGit