[prev in list] [next in list] [prev in thread] [next in thread] 

List:       xmonad
Subject:    Re: [xmonad] How to prefix workspace names with numbers?
From:       Jacek Generowicz <jacek.generowicz () cern ! ch>
Date:       2012-10-09 11:43:46
Message-ID: 871uh7lvkd.fsf () huxley ! i-did-not-set--mail-host-address--so-tickle-me
[Download RAW message or body]


JG> Select workspace by name Automatically switches when unique starting
JG> substring is entered: this means that most workspace switches take
JG> just two keystrokes. And I don't have to remember that, say, files
JG> is 4: I just have to remember that files starts with 'f' (or, in
JG> extremis, 'fi').

HC> Hm, maybe I should get used to that instead, it sounds really
HC> nice. Can you please tell me more about how you have configured it
HC> to switch automatically and/or post the relevant parts of your
HC> xmonad.hs? I use the default keybindings, so I have to hit tab and
HC> return after entering the substring in order to switch, which is a
HC> bit too slow for my liking.

OK, I'll have a go. I won't paste my whole config file, as that could
well overwhelm you with irrelevant nonsense (and I'm embarassed about
how much of a mess some of it is :-).

Let's see, I'll paste sections of my config file, with some commentary
in between

First of all, the ad-hoc spread of keybindings was driving me insane, so
I hacked up something which allows me to define keybindings in tabular
form. This gives me a convenient overview of my current keybindings and
really helps with selecting new keybindings or coming up with a sensible
set of bindings that works for me.  (For the sake of brevity I've elided
some of the action wrapper definitions from the /where/ section, leaving
mostly the ones related to window/workspace manipulation):

--------------------------------------------------------------------------------
myKeyBindingsTable conf = mkKeymap conf $ concat $ table conf
                          
--        key                  M-              M-S-           M-C-           M-S-C-
table conf =
        [ k "<Return>"         __               __        openTerminal            __
        , k "a"            gotoScreen1      sendScreen1   takeScreen1      \
                swapScreen1
        , k "b"            gotoWorkspace    sendWorkspace takeWorkspace    \
                makeWorkspace
        , k "c"            conkeror         emacsclient         __                __
        , k "d"            launchWithDmenu      __              __                __
        , k "e"            wicdNetwork          __              __                __
        , k "f"            fullscreen       mirror        mirror                  __
        , k "g"            gotoMenu'        bringMenu'    windowMenu'      \
                xmonadCommands
        , k "h"                __               __              __                __
        , k "i"                __               __              __                __
        , k "j"                __               __              __                __
        , k "k"            focusUrgent'         __              __         \
                clearUrgents'
        , k "l"            expandMaster     shrinkMaster  incMaster        decMaster 
        , k "m"            gotoMaster           __        shiftMaster'            __
        , k "n"            nextWindow       prevWindow    nextWindowSwap   \
                prevWindowSwap
        , k "o"                __               __              __                __
        , k "p"            prevWindow       nextWindow    prevWindowSwap   \
                nextWindowSwap -- reversed version of 'n'
        , k "q"            restartXMonad        __              __         quitXMonad
        , k "r"                __               __              __                __
        , k "s"            toggleStruts     cntrlCenter         __         \
                swapScreens
        , k "t"            tileFloating         __              __                __
        , k "u"            gotoScreen0      sendScreen0   takeScreen0      \
                swapScreen0
        , k "v"            volumeMuteToggle volumeDown    volumeUp                __
        , k "w"            nextWorkspace    prevWorkspace renameWorkspace' \
                deleteWorkspace
        , k "x"                __               __              __                __
        , k "y"                __               __              __                __
        , k "z"                __               __              __                __
        , k "<Backspace>"  closeWindow          __              __         \
                deleteWorkspace
        , k "<Space>"      nextLayout       prevLayout          __         \
                resetLayout
        , k "-"            gotoRecentWS     sendRecentWS  takeRecentWS            __
        ]
 where
 k key m ms mc msc = 
     [ bind "M-"      key m
     , bind "M-S-"    key ms
     , bind "M-C-"    key mc
     , bind "M-S-C-"  key msc
     ]

 bind modifiers key (U comment action) = (modifiers ++ key, action)
 bind modifiers key (B comment action) = (modifiers ++ key, action $ modifiers ++ \
key)

 __ = B "Available for use"
      (\key -> spawn $ "xmessage '" ++ key ++ " is not bound.'")

 openTerminal     = U "Open a terminal"           (spawn "rxvt-unicode +sb -fg wheat \
-bg grey10")  closeWindow      = U "Close the focused window"  kill
 launchWithDmenu  = U "Dmenu"                     (spawn "exe=`dmenu_path | dmenu` && \
eval \"exec $exe\"")  
 gotoMenu'        = U "Switch to window chosen by name via dmenu"         gotoMenu
 bringMenu'       = U "Bring a window chosen by name via dmenu"           bringMenu
 windowMenu'      = U "Pop up a 'flower' of actions to perform on window" windowMenu
 xmonadCommands   = U "Execute an XMonad command via dmenu"               \
(defaultCommands >>= runCommand)

 gotoScreen0      = U   "Go to screen 0" (onScreen 0 gotoX)
 sendScreen0      = U "Send to screen 0" (onScreen 0 sendX)
 takeScreen0      = U "Take to screen 0" (onScreen 0 takeX)
 gotoScreen1      = U   "Go to screen 1" (onScreen 1 gotoX)
 sendScreen1      = U "Send to screen 1" (onScreen 1 sendX)
 takeScreen1      = U "Take to screen 1" (onScreen 1 takeX)

 gotoRecentWS     = U "Switch to the most recently visited invisible workspace" \
(windows gotoRecent)  sendRecentWS     = U   "Send to the most recently visited \
invisible workspace" (windows sendRecent)  takeRecentWS     = U   "Take to the most \
recently visited invisible workspace" (windows takeRecent)

 gotoWorkspace    = U "Switch to named workspace with autoComplete" (selectWorkspace \
myXPConfig)  makeWorkspace    = U "Switch to named workspace" (selectWorkspace \
myXPConfig { autoComplete = Nothing })  sendWorkspace    = U   "Send to named \
workspace" (withWorkspace myXPConfig sendX)  takeWorkspace    = U   "Take to named \
workspace" (withWorkspace myXPConfig takeX)

 nextWorkspace    = U "Go to next workspace"     (nextWS)
 prevWorkspace    = U "Go to previous workspace" (prevWS)

 renameWorkspace' = U "Rename workspace" (renameWorkspace myXPConfig)
 deleteWorkspace  = U "Remove workspace" (removeWorkspace)

 fullscreen       = U "Toggle fullscreening"     (sendMessage $ Toggle NBFULL)
 mirror           = U "Toggle layout mirrorring" (sendMessage $ Toggle MIRROR)

 expandMaster     = U "Increase the size of the master area" (sendMessage Expand)
 shrinkMaster     = U "Increase the size of the master area" (sendMessage Shrink)
 incMaster        = U "Increase the nummber of windows in the master area" \
(sendMessage (IncMasterN 1))  decMaster        = U "Decrease the nummber of windows \
in the master area" (sendMessage (IncMasterN (-1)))  gotoMaster       = U "Move focus \
to the master window" (windows focusMaster)  shiftMaster'     = U "Make focused \
master, push others down."    (windows shiftMaster)

 -- TODO: + Make focus stay on the originally focused window
 --       + Think about the keybinding
 --       + Generalize to N screens
 swapScreens      = U "Swap currest screen with other"    (windows   swapTopScreens)
 swapScreen0      = U "Swap current screen with screen 0" (windows $ \
swapTopScreenWith 0)  swapScreen1      = U "Swap current screen with screen 1" \
(windows $ swapTopScreenWith 1)

--------------------------------------------------------------------------------

mkKeymap comes from XMonad.Util.EZConfig

The Bs and Us all over the place are mine:

--------------------------------------------------------------------------------
-- Two varieties of Action: B(ound) is aware of the key that was used to
-- invoke it, U(nbound) is not aware of the key.
data Action = U String (          X ()) |
              B String (String -> X ())
--------------------------------------------------------------------------------

I planned to use the string in an automatically generated table of
keybindings that pops up at the behest of a keystroke, but I never got
around to doing that. (Ideas welcome.)

Homing in on the details of your question: from the bindings table you
can see that I use 'b' as my workspace selection key:

--------------------------------------------------------------------------------
        , k "b"            gotoWorkspace    sendWorkspace takeWorkspace    \
                makeWorkspace
--------------------------------------------------------------------------------

The corresponding action wrappers are defined as

--------------------------------------------------------------------------------
 gotoWorkspace    = U "Switch to named workspace with autoComplete" (selectWorkspace \
myXPConfig)  makeWorkspace    = U "Switch to named workspace" (selectWorkspace \
myXPConfig { autoComplete = Nothing })  sendWorkspace    = U   "Send to named \
workspace" (withWorkspace myXPConfig sendX)  takeWorkspace    = U   "Take to named \
                workspace" (withWorkspace myXPConfig takeX)
--------------------------------------------------------------------------------

U is a constructor of my Action type (shown above).

selectWorkspace and withWorkspace come from XMonad.Actions.DynamicWorkspaces

myXPConfig is rather simple:

--------------------------------------------------------------------------------
myXPConfig = defaultXPConfig {
 -- If only one completion remains, auto-select it after 1
 -- microsecond. Increasing the delay could help to stop accidentally
 -- sending keypresses to the newly focused window, but with my
 -- current usage, 1 microsecond is working just fine.
  autoComplete = Just 1
}
--------------------------------------------------------------------------------

defaultXPConfig comes from XMonad.Prompt

I define sendX, takeX:

--------------------------------------------------------------------------------
gotoX = windows . view
sendX = windows . shift
takeX = sendX ->> gotoX

-- Helpers for performing multiple actions on the same entity
infixl 1 ->>
(a ->> b) c = do a c
                 b c
--------------------------------------------------------------------------------

view and shift come from XMonad.StackSet

The whole lot is installed thus:

--------------------------------------------------------------------------------
myConfig = gnomeConfig
    { ...
    , keys = myKeyBindingsTable
    ...
    }
--------------------------------------------------------------------------------

and gnomeConfig comes from XMonad.Config.Gnome (though I suspect that
there's nothing Gnome specific left in my config at all, by now).

I think I've shown all the necessary bits for the core of your question,
if not, don't hesitate to ask.

Hope it will be of some use.

_______________________________________________
xmonad mailing list
xmonad@haskell.org
http://www.haskell.org/mailman/listinfo/xmonad


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic