[BACK]Return to jump.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / less

Annotation of src/usr.bin/less/jump.c, Revision 1.1.1.2

1.1       etheisen    1: /*
1.1.1.2 ! millert     2:  * Copyright (C) 1984-2002  Mark Nudelman
1.1       etheisen    3:  *
1.1.1.2 ! millert     4:  * You may distribute under the terms of either the GNU General Public
        !             5:  * License or the Less License, as specified in the README file.
1.1       etheisen    6:  *
1.1.1.2 ! millert     7:  * For more information about less, or for information on how to
        !             8:  * contact the author, see the README file.
1.1       etheisen    9:  */
                     10:
                     11:
                     12: /*
                     13:  * Routines which jump to a new location in the file.
                     14:  */
                     15:
                     16: #include "less.h"
                     17: #include "position.h"
                     18:
                     19: extern int hit_eof;
                     20: extern int jump_sline;
                     21: extern int squished;
                     22: extern int screen_trashed;
                     23: extern int sc_width, sc_height;
1.1.1.2 ! millert    24: extern int show_attn;
1.1       etheisen   25:
                     26: /*
                     27:  * Jump to the end of the file.
                     28:  */
                     29:        public void
                     30: jump_forw()
                     31: {
                     32:        POSITION pos;
                     33:
                     34:        if (ch_end_seek())
                     35:        {
                     36:                error("Cannot seek to end of file", NULL_PARG);
                     37:                return;
                     38:        }
                     39:        /*
                     40:         * Position the last line in the file at the last screen line.
                     41:         * Go back one line from the end of the file
                     42:         * to get to the beginning of the last line.
                     43:         */
                     44:        pos = back_line(ch_tell());
                     45:        if (pos == NULL_POSITION)
                     46:                jump_loc((POSITION)0, sc_height-1);
                     47:        else
                     48:                jump_loc(pos, sc_height-1);
                     49: }
                     50:
                     51: /*
                     52:  * Jump to line n in the file.
                     53:  */
                     54:        public void
1.1.1.2 ! millert    55: jump_back(linenum)
        !            56:        LINENUM linenum;
1.1       etheisen   57: {
                     58:        POSITION pos;
                     59:        PARG parg;
                     60:
                     61:        /*
                     62:         * Find the position of the specified line.
                     63:         * If we can seek there, just jump to it.
                     64:         * If we can't seek, but we're trying to go to line number 1,
                     65:         * use ch_beg_seek() to get as close as we can.
                     66:         */
1.1.1.2 ! millert    67:        pos = find_pos(linenum);
1.1       etheisen   68:        if (pos != NULL_POSITION && ch_seek(pos) == 0)
                     69:        {
1.1.1.2 ! millert    70:                if (show_attn)
        !            71:                        set_attnpos(pos);
1.1       etheisen   72:                jump_loc(pos, jump_sline);
1.1.1.2 ! millert    73:        } else if (linenum <= 1 && ch_beg_seek() == 0)
1.1       etheisen   74:        {
                     75:                jump_loc(ch_tell(), jump_sline);
                     76:                error("Cannot seek to beginning of file", NULL_PARG);
                     77:        } else
                     78:        {
1.1.1.2 ! millert    79:                parg.p_linenum = linenum;
        !            80:                error("Cannot seek to line number %n", &parg);
1.1       etheisen   81:        }
                     82: }
                     83:
                     84: /*
                     85:  * Repaint the screen.
                     86:  */
                     87:        public void
                     88: repaint()
                     89: {
                     90:        struct scrpos scrpos;
                     91:        /*
                     92:         * Start at the line currently at the top of the screen
                     93:         * and redisplay the screen.
                     94:         */
                     95:        get_scrpos(&scrpos);
                     96:        pos_clear();
                     97:        jump_loc(scrpos.pos, scrpos.ln);
                     98: }
                     99:
                    100: /*
                    101:  * Jump to a specified percentage into the file.
                    102:  */
                    103:        public void
                    104: jump_percent(percent)
                    105:        int percent;
                    106: {
                    107:        POSITION pos, len;
                    108:
                    109:        /*
                    110:         * Determine the position in the file
                    111:         * (the specified percentage of the file's length).
                    112:         */
                    113:        if ((len = ch_length()) == NULL_POSITION)
                    114:        {
                    115:                ierror("Determining length of file", NULL_PARG);
                    116:                ch_end_seek();
                    117:        }
                    118:        if ((len = ch_length()) == NULL_POSITION)
                    119:        {
                    120:                error("Don't know length of file", NULL_PARG);
                    121:                return;
                    122:        }
1.1.1.2 ! millert   123:        pos = percent_pos(len, percent);
1.1       etheisen  124:        if (pos >= len)
                    125:                pos = len-1;
                    126:
                    127:        jump_line_loc(pos, jump_sline);
                    128: }
                    129:
                    130: /*
                    131:  * Jump to a specified position in the file.
                    132:  * Like jump_loc, but the position need not be
                    133:  * the first character in a line.
                    134:  */
                    135:        public void
                    136: jump_line_loc(pos, sline)
                    137:        POSITION pos;
                    138:        int sline;
                    139: {
                    140:        int c;
                    141:
                    142:        if (ch_seek(pos) == 0)
                    143:        {
                    144:                /*
                    145:                 * Back up to the beginning of the line.
                    146:                 */
                    147:                while ((c = ch_back_get()) != '\n' && c != EOI)
                    148:                        ;
                    149:                if (c == '\n')
                    150:                        (void) ch_forw_get();
                    151:                pos = ch_tell();
                    152:        }
1.1.1.2 ! millert   153:        if (show_attn)
        !           154:                set_attnpos(pos);
1.1       etheisen  155:        jump_loc(pos, sline);
                    156: }
                    157:
                    158: /*
                    159:  * Jump to a specified position in the file.
                    160:  * The position must be the first character in a line.
                    161:  * Place the target line on a specified line on the screen.
                    162:  */
                    163:        public void
                    164: jump_loc(pos, sline)
                    165:        POSITION pos;
                    166:        int sline;
                    167: {
                    168:        register int nline;
                    169:        POSITION tpos;
                    170:        POSITION bpos;
                    171:
                    172:        /*
                    173:         * Normalize sline.
                    174:         */
                    175:        sline = adjsline(sline);
                    176:
                    177:        if ((nline = onscreen(pos)) >= 0)
                    178:        {
                    179:                /*
                    180:                 * The line is currently displayed.
                    181:                 * Just scroll there.
                    182:                 */
                    183:                nline -= sline;
                    184:                if (nline > 0)
                    185:                        forw(nline, position(BOTTOM_PLUS_ONE), 1, 0, 0);
                    186:                else
                    187:                        back(-nline, position(TOP), 1, 0);
1.1.1.2 ! millert   188:                if (show_attn)
        !           189:                        repaint_hilite(1);
1.1       etheisen  190:                return;
                    191:        }
                    192:
                    193:        /*
                    194:         * Line is not on screen.
                    195:         * Seek to the desired location.
                    196:         */
                    197:        if (ch_seek(pos))
                    198:        {
                    199:                error("Cannot seek to that file position", NULL_PARG);
                    200:                return;
                    201:        }
                    202:
                    203:        /*
                    204:         * See if the desired line is before or after
                    205:         * the currently displayed screen.
                    206:         */
                    207:        tpos = position(TOP);
                    208:        bpos = position(BOTTOM_PLUS_ONE);
                    209:        if (tpos == NULL_POSITION || pos >= tpos)
                    210:        {
                    211:                /*
                    212:                 * The desired line is after the current screen.
                    213:                 * Move back in the file far enough so that we can
                    214:                 * call forw() and put the desired line at the
                    215:                 * sline-th line on the screen.
                    216:                 */
                    217:                for (nline = 0;  nline < sline;  nline++)
                    218:                {
                    219:                        if (bpos != NULL_POSITION && pos <= bpos)
                    220:                        {
                    221:                                /*
                    222:                                 * Surprise!  The desired line is
                    223:                                 * close enough to the current screen
                    224:                                 * that we can just scroll there after all.
                    225:                                 */
                    226:                                forw(sc_height-sline+nline-1, bpos, 1, 0, 0);
1.1.1.2 ! millert   227:                                if (show_attn)
        !           228:                                        repaint_hilite(1);
1.1       etheisen  229:                                return;
                    230:                        }
                    231:                        pos = back_line(pos);
                    232:                        if (pos == NULL_POSITION)
                    233:                        {
                    234:                                /*
                    235:                                 * Oops.  Ran into the beginning of the file.
                    236:                                 * Exit the loop here and rely on forw()
                    237:                                 * below to draw the required number of
                    238:                                 * blank lines at the top of the screen.
                    239:                                 */
                    240:                                break;
                    241:                        }
                    242:                }
                    243:                lastmark();
                    244:                hit_eof = 0;
                    245:                squished = 0;
                    246:                screen_trashed = 0;
                    247:                forw(sc_height-1, pos, 1, 0, sline-nline);
                    248:        } else
                    249:        {
                    250:                /*
                    251:                 * The desired line is before the current screen.
                    252:                 * Move forward in the file far enough so that we
                    253:                 * can call back() and put the desired line at the
                    254:                 * sline-th line on the screen.
                    255:                 */
                    256:                for (nline = sline;  nline < sc_height - 1;  nline++)
                    257:                {
                    258:                        pos = forw_line(pos);
                    259:                        if (pos == NULL_POSITION)
                    260:                        {
                    261:                                /*
                    262:                                 * Ran into end of file.
                    263:                                 * This shouldn't normally happen,
                    264:                                 * but may if there is some kind of read error.
                    265:                                 */
                    266:                                break;
                    267:                        }
                    268:                        if (pos >= tpos)
                    269:                        {
                    270:                                /*
                    271:                                 * Surprise!  The desired line is
                    272:                                 * close enough to the current screen
                    273:                                 * that we can just scroll there after all.
                    274:                                 */
                    275:                                back(nline+1, tpos, 1, 0);
1.1.1.2 ! millert   276:                                if (show_attn)
        !           277:                                        repaint_hilite(1);
1.1       etheisen  278:                                return;
                    279:                        }
                    280:                }
                    281:                lastmark();
                    282:                clear();
                    283:                screen_trashed = 0;
                    284:                add_back_pos(pos);
                    285:                back(sc_height-1, pos, 1, 0);
                    286:        }
                    287: }