Recently I got a bit fed up with my XMonad configuration and decided to add some of the missing bits. After all I made the switch with productivity in mind so it would be silly to endure even the slightest tradeoffs. If you don’t know what XMonad is – it’s an extremely customizable tiling window manager – the default configuration is, however, pretty crude, so it doesn’t really make sense to switch if you’re not going to tweak it, even if just slightly.
To the point – one of the things I was missing was the ability to open a new terminal emulator window in the same working directory as the one I had focused. I felt that existing solutions such as the WorkspaceDir extension were lacking and not exactly what I was looking for. And so I had to write one myself. Since I figured I couldn’t be the only one in need I decided I’d share my snippet.
The Code
The solution involves overriding the “new terminal” binding and changing the directory to focused window’s CWD
. In order to do so we have to extract it first – depending on what OS you are sitting on the actual script may vary – so just for the record, the script shown below was written for a Linux-based distro, although it should work on other operating systems with a proper /proc
filesystem too.
- Add key binding – note, I’m using EZConfig here
("S-M-<Return>", mkTerm)
{:start="2”} 2. Add terminal launcher
mkTerm = withWindowSet launchTerminal
launchTerminal ws = case peek ws of
Nothing -> runInTerm "" "$SHELL"
Just xid -> terminalInCwd xid
{:start="3”} 3. Detect current working directory of focused window. You may need a different way of obtaining the CWD from PID if not on Linux (I was being lazy, sorry).
terminalInCwd xid = let
hex = showHex xid " "
shInCwd = "'cd $(readlink /proc/$(ps --ppid $(xprop -id 0x" ++ hex
++ "_NET_WM_PID | cut -d\" \" -f3) -o pid= | tr -d \" \")/cwd) && $SHELL'"
in runInTerm "" $ "sh -c " ++ shInCwd
{:start="4”} 4. Last but not least – make sure to add missing imports
import Numeric
import XMonad.Core
import XMonad.StackSet
import XMonad.Util.Run
That’s it
From now on you can let your fingers rest a bit more – enjoy! And make sure to plan carefully what you’re going to do with the time saved as well!
As usual, if you want to have a closer look at a config actually using this it’s avaialable as part of my dotfiles repo.