Tuesday, October 25, 2011

Opening new browser tab when Caps Lock key is pressed

After using a Chromebook for a while, I realised how useful mapping Caps Lock key to opening a new browser tab can be.  Of course, it’s possible to set up key bindings to achieve this in Linux.

First, I set up .Xmodmap so that pressing Caps Lock is interpreted as the same as pressing Calculator key on my multimedia keyboard.  I chose Calculator key because it doesn’t currently do anything, and I don’t use it at all.  I added the following lines to my ~/.Xmodmap file.
remove Lock = Caps_Lock
keysym Caps_Lock = XF86Calculator
Now, pressing Caps Lock would be the same as pressing Calculator key.

We need to make pressing Calculator key send Ctrl+T keystrokes instead.  This can be done in KDE by defining a new global shortcut.  In KDE 4.7, this is done by navigating to System Settings > Shortcuts and Gestures > Custom Shortcuts.  Define a new Command/URL global shortcut.  Use Caps Lock as the trigger shortcut (it would show as Calculator in the UI).  Specify
/usr/bin/xte "keydown Control_L" "key t" "keyup Control_L"
as the command to run.  (You’d have to install xte if it isn’t already installed on your machine.)  That’s it; now pressing Caps Lock anywhere within KDE would send Ctrl+T keystrokes instead.

A few tips:
  • You can use xmodmap -pk command to see the list of all available keys.
  • Be sure to select a key that’s actually present on your keyboard; my laptop does not have a calculator key, so I am using the battery key instead.  Any key that's present in the keyboard but not currently in use would do.
  • After you have modified your ~/.Xmodmap, you’ll have to log out and log back in for the mappings to apply.  Alternatively, you can apply the configuration to your current session from the command line, e.g. by running xmodmap -e "remove Lock = Caps_Lock".

Sunday, October 23, 2011

zsh syntax highlighting

I like colours.  I have aliased all frequently used commands like ls, grep, etc. by adding flags to show colours in the output.  I have set my PS1 in such a way that the prompt is in a different colour.  It makes it easy for me to see where the prompt ends and the command starts.  When I heard about fish and that it does syntax highlighting, I was tempted to switch to it.  But I couldn’t because it didn’t do certain things I needed.  (I don’t remember the details now.)  Soon after that I found out that it’s very simple to add syntax highlighting to zsh!

All you have to do is download the code from zsh-syntax-highlighting project and “source” it in your .zshrc.  But I wasn’t happy with their defaults.  By default this script underlines path names, but I hate underlining because it makes text less readable.  I also didn’t like their choice of blue colour for globs.  On my black terminal, blue is hardly readable.  Customising the formatting was easy too; I only had to change the value of a variable.  This is what my .zshrc has now, and syntax highlighting works like a charm.
source ~/dload/src/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
You can find the list of different syntax highlighting options in this file.

Thursday, October 20, 2011

Terminating scripts when any individual command fails

Let’s say you have a script that builds a project, runs all tests, and pushes the binary to a staging/production server.  If the build fails or a test fails you’d want the script to stop immediately.  Pushing a binary that failed some tests is obviously wrong.  You can check for a command’s return value using if and terminate your script.  But doing that for every command in the script would make your script less readable and more prone to bugs.

Shells provide a clean solution for this use case: you can set a script-level option to stop the script execution if any command you invoke from the script exits with a non-zero status.  You do that in bash using
set -e
and in zsh using
setopt err_exit
So your script would essentially look like this:
set -e
make test
make push
zsh also has a err_return option that can be set to make a function return (as opposed to terminating the whole script) when a command invoked by a function fails.