Here is a cool trick for users of multiple shell windows on Linux

How often do you have about a dozen shell windows open? Let's add two capabilities to make that easier. These are controlled with a line that looks like this in the script:

export PROMPT_COMMAND="shareHistory; testWindow"

You can simply remove the feature you don't want from your PROMPT_COMMAND, or change it on a window-by-window basis if you like.

  • shareHistory — Consolidate the bash history so that it is available through any bash that your username controls. The history will sync after every command. The only drawback is that it's AFTER every command, so you might want to hit enter if you just switched windows to ensure that the commands you just used in the other window are available in this window. Hit ENTER to sync up, then use up-arrow, history, or ! commands as if you never swiched windows.
  • fixTitle — This one happens as part of the testWindow command below. It updates the window title to the command you just ran so that you always know whats running in that window.
  • testWindow — testWindow - You probably switched windows because you are waiting on something to finish, like an emerge. Wouldn't it be nice to know when it's done? This command will look and see if its currently on top and if not, it will issues a notification to your desktop to let you know the last command finished. It even selects an appropriate icon. Its silent as long as window is on top. This is sort of a hack since bash doesn't know anything about your window stack. Instead, a couple commands are aliased to look at the window that currently has focus (which should be itself since you are typing the command!) and records this. You shouldn't use commands that record the window in a script. You can also force it to remember the window with the new command n.

Also, the testWindow functionality is set up to not try to remember the window when the script starts. This is because your bash profile starts to run before the window is open and gets focus creating a race condition. You have to specifically turn on the feature with 'n'. I've also aliased 'ls' and 'emerge' to turn this on as well (and record the window via 'updateWindowId'). None of the fixTitle or textWindow features work until you use one of these commands.

To use, save the following script as /usr/local/bin/windowtricks.bash

#!/bin/bash #- #- This is to display notifications when you aren't watching the window #- and updates the window title with the currently running command. #- The command is reset when it finishes, unless the window is on top. #- In this case, the window title is kept so you can find it. You #- may use the 'n' command to manually reset the window title. #- #- We should only update the WindowId when the window has focus! #- This means the first update can't be inside .bashrc #- #- The new 'n' command updates the 'notify' and resets title to $SHELL #- #- source this file from your .bashrc #- shopt -s histappend alias n='updateWindowId; fixTitle; initTrap' #- These commands will automatically call n to turn on the features alias ls='n; ls --color=tty' # alias cd='n; cd' alias emerge='n; emerge' #- keep this info resetTaskName() { LC_TASK=$(basename ${SHELL}) } #- need to remember this updateWindowId() { LC_XWINDOWID=$(xdotool getactivewindow) #resetTaskName if [ -z "$LC_NAME" ]; then LC_NAME=$(xdotool getwindowname $LC_XWINDOWID) fi } #- actually set the window title fixTitle() { #- If we have a 'screen' type terminal, name the screen, not the window case $TERM in screen) echo -ne "\033k${LC_TASK}\033\\" ;; xterm|xterm-256color|xterm-color|Eterm|aterm|rxvt|kterm|rxvt-unicode|gnome|interix) echo -ne "\x1b]0;${LC_NAME}: ${LC_TASK}\x07" ;; esac } #- get command for title autoTitle() { case $BASH_COMMAND in fixTitle) ;; testWindow) ;; updateWindowId) ;; getLastCommand) ;; sendNotify) ;; *) LC_TASK=$BASH_COMMAND fixTitle ;; esac } #- grab from history getLastCommand() { LC_TASK=$(history 1 | cut -c 8-) LC_ICON=$(basename $LC_TASK 2>/dev/null) if [ -z "$LC_ICON" ]; then LC_ICON="utilities-terminal" else #- FIXME: This is a bad/slow hack. eval $(locate $LC_ICON.desktop | xargs cat | grep Icon | head -1 | sed 's/Icon/LC_ICON/') 2>/dev/null fi } #- notification of task completion sendNotify() { getLastCommand notify-send -t 10000 -i "$LC_ICON" "Task Complete in $LC_NAME" "$LC_TASK" } #- test to see if window is on top testWindow() { LC_ACTIVE=$(xdotool getactivewindow 2>/dev/null) if [ -z "$LC_XWINDOWID" ]; then return 0; fi if [ "$LC_ACTIVE" != "$LC_XWINDOWID" ]; then #- This command is forked because it takes too long sendNotify & disown 2>/dev/null else #- comment these 3 lines to keep last command in title resetTaskName #- above and this one fixTitle #- and this one fi } #- This trick shares history in all open bash windows shareHistory() { history -a history -c history -r } #- the magic! Executed when prompt is displayed export PROMPT_COMMAND="shareHistory; testWindow" #- some magic for updating window title initTrap () { if [ -z "$LC_INIT" ]; then #- These commands update the windowid in case #- our shell moved from one window to another alias ls='updateWindowId; ls --color=tty' alias cd='updateWindowId; cd' #- The rest we just unalias unalias emerge LC_INIT="DONE" trap autoTitle DEBUG fi }

Now, change your .bashrc and add to load this file, like this:

source /usr/local/bin/windowtricks.bash

Enjoy!