6.2. Cursor Movement

ANSI escape sequences or tput allow you to move the cursor around the screen at will. This is more useful for full screen user interfaces generated by shell scripts, but can also be used in prompts. I recommend against it, but I used it a lot before I came to that conclusion: I'll give you the information, you decide for yourself.

For a more general discussion of ANSI escape codes, see the appropriate entry at Wikipedia: http://en.wikipedia.org/wiki/ANSI_escape_code.

tput Cursor Movement Capabilities

tput cup Y X

Move cursor to screen location X,Y (top left is 0,0)

tput sc

Save the cursor position

tput rc

Restore the cursor position

tput lines

Output the number of lines of the terminal

tput cols

Output the number of columns of the terminal

tput cub N

Move N characters left

tput cuf N

Move N characters right

tput cub1

move left one space

tput cuf1

non-destructive space (move right one space)

tput ll

last line, first column (if no cup)

tput cuu1

up one line

ANSI escape sequences are unreliable: the ones that seem most important (save and restore cursor position) don't work in the majority of modern X terminals. tput results in relatively more readable commands, and has a more extensive command set. Because of this, I implement any movement code using tput not ANSI escape sequences. Nevertheless, here are the codes for those who want to use them:

- Position the Cursor:
  \033[<L>;<C>H
     Or
  \033[<L>;<C>f
  puts the cursor at line L and column C.
- Move the cursor up N lines:
  \033[<N>A
- Move the cursor down N lines:
  \033[<N>B
- Move the cursor forward N columns:
  \033[<N>C
- Move the cursor backward N columns:
  \033[<N>D

- Clear the screen, move to (0,0):
  \033[2J
- Erase to end of line:
  \033[K

- Save cursor position:
  \033[s
- Restore cursor position:
  \033[u

The latter two codes are NOT honoured by many terminal emulators. The only ones that I'm aware of that do are xterm and nxterm - even though the majority of terminal emulators are based on xterm code. As far as I can tell, aterm, rxvt, kvt, xiterm, and Eterm do not support them. They are supported on the console.

Try putting in the following line of code at the prompt (it's a little clearer what it does if the prompt is several lines down the terminal when you put this in): echo -n "$(tput sc ; tput cuu 3 ; tput cuf 12 ; tput setab 5 ; tput setaf 7) BASH $(tput sgr0 ; tput rc)" This command uses tput for both cursor movement and colour. To be exact, it executes the following steps inside the echo command: save the cursor position (sc), go up three lines (cuu 3), go twelve characters right (cuf 12), set a magenta background (setab 5), set a white foreground (setaf 7). Echo the actual text. Reset all colours to defaults (sgr0), and restore the cursor position to where we started (sc). This isn't a prompt: it's just a demonstration of moving the cursor on screen, using colour to emphasize what has been done.

Save this in a file called "clock":

#!/bin/bash

function prompt_command {
let prompt_x=$(tput cols)-7
}

PROMPT_COMMAND=prompt_command

function clock {
local       BLUE="\[\033[0;34m\]"
local        RED="\[\033[0;31m\]"
local  LIGHT_RED="\[\033[1;31m\]"
local      WHITE="\[\033[1;37m\]"
local  NO_COLOUR="\[\033[0m\]"
case $TERM in
    xterm*)
        TITLEBAR='\[\033]0;\u@\h:\w\007\]'
        ;;
    *)
        TITLEBAR=""
        ;;
esac

PS1="${TITLEBAR}\
\[$(tput sc ; tput cup 0 ${prompt_x})\]\
$BLUE[$LIGHT_RED\D{%H%M}$BLUE]\
\[$(tput rc)\]\
$BLUE[$LIGHT_RED\u@\h:\w$BLUE]\
$WHITE\$$NO_COLOUR "
PS2='> '
PS4='+ '
}

This prompt is fairly plain, except that it keeps a 24 hour clock in the upper right corner of the terminal (even if the terminal is resized). tput cols supplies the number of columns in the current terminal.

See also Section 11.9 for extensive use of ANSI movement codes.