Seleciona interativamente uma linha no terminal

0

Eu estou procurando um programa como less que eu possa passar um monte de linhas de texto e fazer o usuário interativamente selecionar uma.

Isso será usado para visualizar e selecionar o histórico do shell, embora eu provavelmente venha com outros usos.

Alguém sabe de tal programa?

Estou pensando em usar o módulo zshurs zsh para criá-lo, mas isso seria muito trabalhoso. Se houver outra opção mais fácil que seria preferível.

    
por RedHatter 24.10.2015 / 02:32

1 resposta

0

Usar o módulo zcurses foi muito mais fácil do que eu pensava. Foi isso que eu criei.

#!/bin/zsh
#
# Usage:
#   Call 'many.init [listname] [values]' then 'many.loop' when it returns REPLY
#   will be set to the selected value.
#
# Example:
#   many.init History $history
#   many.loop
#   echo $REPLY
#
##

zmodload zsh/curses

(( size=LINES ))

typeset -i selected pos
pos=1
selected=$size

many.init ()
{
    name=$1
    shift
    elements=( "$@" )
    zcurses init
    many.draw
}

many.loop ()
{
    while true; do
        zcurses input stdscr raw key
        many.read $raw $key || return
    done
}

many.read ()
{
    case $1 in 
        'q')
            zcurses end
            typeset -g REPLY
            REPLY=$elements[selected]
            return 1
            ;;
        "UP")
            if (( selected > 1 )); then
                (( selected <= pos)) && (( pos-- ))
                (( selected-- ))
            fi
            ;;
        "DOWN")
            if (( selected < ${#elements} )); then
                (( selected >= pos+size-1)) && (( pos++ ))
                (( selected++ ))
            fi
            ;;
        "PPAGE")
            (( pos=pos-size, selected=selected-size ))
            (( pos < 1 )) && pos=1
            (( selected < 1 )) && selected=1
            ;;
        "NPAGE")
            (( pos=pos+size, selected=selected+size ))
            (( pos > ${#elements} )) && pos=${#elements}
            (( selected > ${#elements} )) && selected=${#elements}
            ;;
    esac

    many.draw
}

many.draw ()
{
    typeset -i offset
    offset=0
    zcurses clear stdscr
    for (( i=0; i+offset < size; i++ )); do
        if (( i+pos == selected )); then
            zcurses attr stdscr black/white
            lines=( ${(@fr:$COLUMNS:)elements[i+pos]} )
            zcurses string stdscr "${(j::)lines}"
            (( offset=offset+${#lines}-1 ))
            zcurses attr stdscr default/default
        else
            zcurses string stdscr "${elements[i+pos]/
*/...}
"
        fi
    done
    zcurses attr stdscr white/black
    zcurses string stdscr "$name line $selected (Press 'q' to select)"
    zcurses attr stdscr default/default
    zcurses refresh
}
    
por RedHatter 25.10.2015 / 01:06