
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.