aitee
aitee

Reputation: 91

History -- Control screen scrolling through text in place (up arrow -> cycle though commands in place/same location)

When you scroll through the history the text changes at the prompt. I've looked at the structures involved but haven't looked deep enough in the source code to find out how it changes the text on the screen without changing all the text above it (the prompt, past text that has been printed out.)

It can't just clear the screen and reprint everything out with only the minor change after the prompt-- that would just be so inefficient. How do they do this?

It probably sounds really dumb, but I tried printing a backspace character which results in moving the cursor into the prompt in which when you type it just writes over top of the prompt.

I just can't figure how they print out text and change it or cycle through text in place.

If anyone knows how this is done I would really appreciate it.

Thanks

Upvotes: 0

Views: 290

Answers (1)

geekosaur
geekosaur

Reputation: 61369

bash uses the GNU readline library to do this. It's ultimately a wrapper over the terminfo library (from System V or the ncurses library), whose purpose is to use terminal descriptions to figure out how to do those updates. If the terminal type is unknown or declared incorrectly, you'll notice that you either end up with garbage or all the pretty in-place updates go away.

A terminal description looks something like

xterm-color|nxterm|generic color xterm,
        am, km, mir, msgr, xenl,
        colors#8, cols#80, it#8, lines#24, ncv@, pairs#64,
        acsc=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
        bel=^G, bold=\E[1m, clear=\E[H\E[2J, cr=^M,
        csr=\E[%i%p1%d;%p2%dr, cub=\E[%p1%dD, cub1=^H,
        cud=\E[%p1%dB, cud1=^J, cuf=\E[%p1%dC, cuf1=\E[C,
        cup=\E[%i%p1%d;%p2%dH, cuu=\E[%p1%dA, cuu1=\E[A,
        dch=\E[%p1%dP, dch1=\E[P, dl=\E[%p1%dM, dl1=\E[M, ed=\E[J,
        el=\E[K, enacs=\E)0, home=\E[H, ht=^I, hts=\EH, il=\E[%p1%dL,
        il1=\E[L, ind=^J,
        is2=\E[m\E[?7h\E[4l\E>\E7\E[r\E[?1;3;4;6l\E8, kbs=^H,
        kcub1=\EOD, kcud1=\EOB, kcuf1=\EOC, kcuu1=\EOA,
        kdch1=\E[3~, kf1=\E[11~, kf10=\E[21~, kf11=\E[23~,
        kf12=\E[24~, kf13=\E[25~, kf14=\E[26~, kf15=\E[28~,
        kf16=\E[29~, kf17=\E[31~, kf18=\E[32~, kf19=\E[33~,
        kf2=\E[12~, kf20=\E[34~, kf3=\E[13~, kf4=\E[14~,
        kf5=\E[15~, kf6=\E[17~, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~,
        kfnd=\E[1~, kich1=\E[2~, kmous=\E[M, knp=\E[6~, kpp=\E[5~,
        kslt=\E[4~, meml=\El, memu=\Em, op=\E[m, rc=\E8, rev=\E[7m,
        ri=\EM, rmacs=^O, rmcup=\E[2J\E[?47l\E8, rmir=\E[4l,
        rmkx=\E[?1l\E>, rmso=\E[m, rmul=\E[m,
        rs2=\E[m\E[?7h\E[4l\E>\E7\E[r\E[?1;3;4;6l\E8, sc=\E7,
        setab=\E[4%p1%dm, setaf=\E[3%p1%dm, sgr0=\E[m, smacs=^N,
        smcup=\E7\E[?47h, smir=\E[4h, smkx=\E[?1h\E=, smso=\E[7m,
        smul=\E[4m, tbc=\E[3g, u6=\E[%i%d;%dR, u7=\E[6n,
        u8=\E[?1;2c, u9=\E[c,

and describes how to do various screen updates, what function and action keys are available and what they send, and special terminal behaviors (line-drawing characters, colors and other forms of highlighting, whether it can insert characters in the middle of a line, etc.). You don't need to understand it, usually, unless something is set up wrong or you're into advanced terminal hackery. (If you do want to understand it, start with terminfo(5) and the other curses/ncurses/terminfo documentation. If nothing else, you'll learn how to make really fancy shell prompts.)

Upvotes: 3

Related Questions