5

I just realized that I hunch over a lot when using the terminal since the prompt is always at the bottom of the terminal window, which is vertically maximized.

I would like the prompt to be at the vertical middle of the window (or in a point near where my eyes are pointed to).

You could argue that I can resize the window and achieve that, but sometimes I like the vertical space (eg. when running ls -la). So, ideally, I could toggle the position of the prompt between some point and the bottom of the window.

(I'm using iTerm under MacOS with zsh, but I'm interested in an agnostic/generic way of doing this)

2 Answers 2

7

The following code (uses zsh features, but the priciple can be used with other shells, too) defines two shell functions, prompt_middle and prompt_restore.

The first function keeps the prompt always above the middle of the terminal by forcing an appropriate number of empty lines below the prompt. The latter funtion restores the normal behavior.

You can assign these functions to some shortcuts or use some logic to toggle between these two modes.

# load terminfo modules to make the associative array $terminfo available
zmodload zsh/terminfo 

# save current prompt to parameter PS1o
PS1o="$PS1"

# calculate how many lines one half of the terminal's height has
halfpage=$((LINES/2))

# construct parameter to go down/up $halfpage lines via termcap
halfpage_down=""
for i in {1..$halfpage}; do
  halfpage_down="$halfpage_down$terminfo[cud1]"
done

halfpage_up=""
for i in {1..$halfpage}; do
  halfpage_up="$halfpage_up$terminfo[cuu1]"
done

# define functions
function prompt_middle() {
  # print $halfpage_down
  PS1="%{${halfpage_down}${halfpage_up}%}$PS1o"
}

function prompt_restore() {
  PS1="$PS1o"
}

Personally instead of toggling between two modes I would use a much simpler approach (you need the definitions of $halfpage_up/down from above):

magic-enter () {
    if [[ -z $BUFFER ]]
    then
            print ${halfpage_down}${halfpage_up}$terminfo[cuu1]
            zle reset-prompt
    else
            zle accept-line
    fi
}
zle -N magic-enter
bindkey "^M" magic-enter

This checks if the current command line is empty (see my other answer) and if so move the prompt up to the middle of the terminal. Now you can fast-forward your prompt with an additional press of the ENTER key (or maybe you want to call it double-press similar to a double-click).

3
  • This magic-enter function is amazingly handy. Would you have an idea of a bash equivalent?
    – Leonard
    Nov 12, 2019 at 8:46
  • @Léonard: Unfortunately I don't know how bash handles the prompt and terminfo sequences... and how to bind functions to keys, so I'm sorry that my answer to your question is ,no'.
    – mpy
    Nov 12, 2019 at 17:41
  • Thanks @mpy, I will ask the question in a separate post.
    – Leonard
    Nov 19, 2019 at 8:00
2

I use tput cup

Add the below to .zshrc

alias ptop='tput cup $((LINES/4)) 0'  # Clear quarter
alias pmid='tput cup $((LINES/2)) 0'  # Clear half
alias pdown='tput cup $((3*LINES/4)) 0' # Clear 3/4th

NOTE: the problem with this approach is - the screen content is removed.

However, if you are interested in preserving the content of the screen, use the below instead

# Get ceiling eg: 7/2 = 4
ceiling_divide() {
  ceiling_result=$((($1+$2-1)/$2))
}

clear_rows() {
  POS=$1
  # Insert Empty Rows to push & preserve the content of screen
  for i in {1..$((LINES-POS-1))}; echo
  # Move to POS, after clearing content from POS to end of screen
  tput cup $((POS-1)) 0
}

# Clear quarter
alias ptop='ceiling_divide $LINES 4; clear_rows $ceiling_result'
# Clear half
alias pmid='ceiling_divide $LINES 2; clear_rows $ceiling_result'
# Clear 3/4th
alias pdown='ceiling_divide $((3*LINES)) 4; clear_rows $ceiling_result'

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .