XMonad.Actions.Profiles

xmonad-contrib-0.18.1: Community-maintained extensions for xmonad

Copyright | (c) Mislav Zanic
License | BSD3-style (see LICENSE)
Maintainer | Mislav Zanic <mislavzanic3@gmail.com>
Stability | experimental
Portability | unportable
Safe Haskell | None
Language | Haskell2010

XMonad.Actions.Profiles

Contents

- Overview
- Usage
- Types
- Hooks
- Switching profiles
- Workspace navigation and keybindings
- Loggers and pretty printers
- Prompts
- Utilities

Description

Synopsis

- type ProfileId = String
- data Profile = Profile {
  - profileId :: !ProfileId
  - profileWS :: ![WorkspaceId]
  }
- data ProfileConfig = ProfileConfig {
  - workspaceExcludes :: ![WorkspaceId]
  - profiles :: ![Profile]
  - startingProfile :: !ProfileId
  }
- addProfiles :: forall (a :: Type -> Type). ProfileConfig -> XConfig a -> XConfig a
- addProfilesWithHistory :: forall (a :: Type -> Type). ProfileConfig -> XConfig a -> XConfig a
- switchToProfile :: ProfileId -> X ()
- wsFilter :: WSType
- bindOn :: [(String, X ())] -> X ()
- excludeWSPP :: PP -> X PP
- profileLogger :: (String -> String) -> (String -> String) -> Logger
- switchProfilePrompt :: XPConfig -> X ()
- addWSToProfilePrompt :: XPConfig -> X ()
- removeWSFromProfilePrompt :: XPConfig -> X ()
- switchProfileWSPrompt :: XPConfig -> X ()
- shiftProfileWSPrompt :: XPConfig -> X ()
- currentProfile :: X ProfileId
- profileIds :: X [ProfileId]
- previousProfile :: X (Maybe ProfileId)
- profileHistory :: X (Map ProfileId [(ScreenId, WorkspaceId)])
- allProfileWindows :: XWindowMap
- profileWorkspaces :: ProfileId -> X [WorkspaceId]

# Overview

This module allows you to group your workspaces into `Profile`s based on certain similarities. The idea is to expand upon the philosophy set by XMonad.Actions.TopicSpace which states that you can look at a topic/workspace as a single unit of work instead of multiple related units of work. This comes in handy if you have lots of workspaces with windows open and need only to work with a few of them at a time. With `Profile`s, you can focus on those few workspaces that require your attention by not displaying, or allowing you to switch to the rest of the workspaces. The best example is having a profile for development and a profile for leisure activities.

# Usage

To use `Profiles` you need to add it to your XMonad configuration and configure your profiles.

First you'll need to handle the imports.

    import XMonad.Actions.Profiles
    import XMonad.Util.EZConfig -- for keybindings
    import qualified XMonad.StackSet as W
    import qualified XMonad.Actions.DynamicWorkspaceOrder as DO -- for workspace navigation

Next you'll need to define your profiles.

    myStartingProfile :: ProfileId
    myStartingProfile = "Work"

    myProfiles :: [Profile]
    myProfiles =
     [ Profile { profileId = "Home"
               , profileWS = [ "www"
                             , "rss"
                             , "vid"
                             , "vms"
                             , "writing"
                             , "notes"
                             ]
               }
     , Profile { profileId = "Work"
               , profileWS = [ "www"
                             , "slack"
                             , "dev"
                             , "k8s"
                             , "notes"
                             ]
               }
     ]

So, while using `Home` `Profile`, you'll only be able to see, navigate to and do actions with `["www", "rss", "vid", "vms", "writing", "notes"]` workspaces.

You may also need to define some keybindings. Since `M-1` .. `M-9` are sensible keybindings for switching workspaces, you'll need to use `bindOn` to have different keybindings per profile. Here, we'll use XMonad.Util.EZConfig syntax:

    myKeys :: [(String, X())]
    myKeys =
      [ ("M-p",  switchProfilePrompt   xpConfig)
      , ("M-g",  switchProfileWSPrompt xpConfig)
      , ("M1-j", DO.moveTo Next wsFilter)
      , ("M1-k", DO.moveTo Prev wsFilter)
      ]
      <>
      [ ("M-" ++ m ++ k, bindOn $ map (\x -> (fst x, f $ snd x)) i)
      | (i, k) <- map (\(x:xs) -> (map fst (x:xs), snd x)) $ sortGroupBy snd tupleList
      , (f, m) <- [(mby $ windows . W.greedyView, ""), (mby $ windows . W.shift, "S-")]
      ]
      where
        mby f wid = if wid == "" then return () else f wid
        sortGroupBy f = groupBy (\ x y -> f x == f y) . sortBy (\x y -> compare (f x) (f y))
        tupleList = concatMap (\p -> zip (map (\wid -> (profileId p, wid)) (profileWS p <> repeat "")) (map show [1..9 :: Int])) myProfiles

After that, you'll need to hook `Profiles` into your XMonad config:

    main = xmonad $ addProfiles def { profiles        = myProfiles
                                    , startingProfile = myStartingProfile
                                    }
                  $ def `additionalKeysP` myKeys

# Types

type ProfileId = String #

data Profile #

Profile representation.

Constructors

Profile |
Fields profileId :: !ProfileId Profile name. profileWS :: ![WorkspaceId] A list of workspaces contained within a profile.

data ProfileConfig #

User config for profiles.

Constructors

ProfileConfig |
Fields workspaceExcludes :: ![WorkspaceId] A list of workspaces to exclude from the `profileHistoryHook`. profiles :: ![Profile] A list of user-defined profiles. startingProfile :: !ProfileId Profile shown on startup.

#### Instances

Instances details

Default ProfileConfig # |
Instance details Defined in XMonad.Actions.Profiles Methods def :: ProfileConfig #

# Hooks

addProfiles :: forall (a :: Type -> Type). ProfileConfig -> XConfig a -> XConfig a #

Hook profiles into XMonad. This function adds a startup hook that sets up ProfileState. Also adds an afterRescreenHook for viewing correct workspaces when adding new screens.

addProfilesWithHistory :: forall (a :: Type -> Type). ProfileConfig -> XConfig a -> XConfig a #

Hooks profiles into XMonad and enables Profile history logging.

# Switching profiles

switchToProfile :: ProfileId -> X () #

Switch to a profile.

# Workspace navigation and keybindings

wsFilter :: WSType #

For cycling through workspaces associated with the current.

bindOn :: [(String, X ())] -> X () #

Create keybindings per profile.

# Loggers and pretty printers

excludeWSPP :: PP -> X PP #

Pretty printer for a bar. Prints workspace ids of current profile.

profileLogger :: (String -> String) -> (String -> String) -> Logger #

Loggs currentProfile and all profiles with hidden workspaces (workspaces that aren't shown on a screen but have windows).

# Prompts

switchProfilePrompt :: XPConfig -> X () #

Prompt for switching profiles.

addWSToProfilePrompt :: XPConfig -> X () #

Prompt for adding a workspace id to a profile.

removeWSFromProfilePrompt :: XPConfig -> X () #

Prompt for removing a workspace from a profile.

switchProfileWSPrompt :: XPConfig -> X () #

Prompt for switching workspaces.

shiftProfileWSPrompt :: XPConfig -> X () #

Prompt for shifting windows to a different workspace.

# Utilities

currentProfile :: X ProfileId #

Returns current profile.

profileIds :: X [ProfileId] #

Returns ids of all profiles.

previousProfile :: X (Maybe ProfileId) #

Returns previous profile.

profileHistory :: X (Map ProfileId [(ScreenId, WorkspaceId)]) #

Returns the history of viewed workspaces per profile.

allProfileWindows :: XWindowMap #

`XWindowMap` of all windows contained in a profile.

profileWorkspaces :: ProfileId -> X [WorkspaceId] #

Returns the workspace ids associated with a profile id.