How to open a new terminal on the current working directory in i3
Often times I want to spin off a new terminal window on the current directory I am working on. I use gnome-terminal, and if you just type in ‘gnome-terminal’ it does spawn a new terminal process on the current directory; but more often than not I am just using my i3 shortcut to open a new terminal window (ctrl+enter); but that just opens it on $HOME.
To make i3 open a new terminal, I thought of:
- Get the current focused window (i.e. my current terminal)
- Get the window’s process working directory
- Use it as working directory for the new terminal
There are many ways to get the PID of the current focused window, I decided to use xprop. It is not the simplest, but I did not want to install any new tools.
The following will print a bunch of details about the current window, including PID and Title.
xprop -id $(xprop -root -f _NET_ACTIVE_WINDOW 0x " \$0\\n" _NET_ACTIVE_WINDOW | awk "{print \$2}")
I am using gnome-terminal, which uses a background process to spawn new children. A side effect of this is that the parent process owns the window, and that process’ current directory is not what the actual shell is using.
The hacky solution I went with was to just get the current directory from the window’s title, since, well, I already have it there and xprop returns the title along with the PID :). I added a directory existence check and pass it to gnome-terminal as an argument in the script I configured i3 to call when starting a new process.
#!/bin/bash
# gets the currently focused window's id
current_focused_window_id=$(xprop -root -f _NET_ACTIVE_WINDOW 0x " \$0\\n" _NET_ACTIVE_WINDOW | awk "{print \$2}")
# get the tile for the current window
window_title=$(xprop -id $current_focused_window_id | sed -ne 's/WM_NAME(STRING) = "\(.*\)"/\1/p')
# in my set up the title looks like "user@machine:path", this line uses sed to graph the path only after :
preferred_cwd=$(echo $window_title | sed -e 's/.*://')
# expand ~
preferred_cwd="${preferred_cwd//\~/$HOME}"
# if path points to a valid directory, pass it to gnome-terminal
[[ -d "$preferred_cwd" ]] && ARGS="$ARGS --working-directory=$preferred_cwd "
gnome-terminal $ARGS $*